No AWK:
{
sub(",", "", $0); # kill first comma, thanks Thomas
cmd="date -d \""$1" "$2" "$3" "$4" "$5" 1 day ago\" \"+%b %e\"";
cmd|getline dt;
close(cmd);
if (dt==prev && blah==substr($0, index($0, $6))) { times = times + 1 }
else { print times" "line; times = 1 };
prev=$2" "$3;
blah=substr($0, index($0,$6));
line=$0;
}
END { print times" "line }
Supondo que tenhamos esta entrada dentro de um arquivo chamado blah.log
:
Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH
E o script awk em consecutive.awk
, podemos fazer:
$ awk -f consecutive.awk blah.log
3 Tue Aug 23 2016 04:22:11 BLAH
1 Thu Aug 25 2016 05:00:00 BLAH
O que dá o número de dias consecutivos como uma coluna extra e imprime a última data. Para se livrar da data na saída, você pode simplesmente alterar print times" "line
para print times" "blah
(nos dois lugares que aparece).
Como funciona:
- Executa o comando date para obter Ontem da linha atual, obrigado glenn jackman
- Compara a data salva da linha anterior
- Incrementa um contador ou imprime
- Salva os dados da linha atual para a próxima execução
Notas:
- É feio (todo o código AWK é, supere isso)
- Funciona bem em todas as lacunas (até um ano inteiro) porque usa
date
, mas desconsidera os fusos horários - Considera que o BLAH pode ser diferente em linhas diferentes e corresponde apenas às ocorrências do BLAH em relação a outras ocorrências do BLAH. Se o arquivo não estiver bem ordenado, talvez seja necessário executar um
sort -t , -k 2
. - Se você precisar considerar valores diferentes de BLAH, precisará do GNU awk (graças à chamada
substr
). Caso contrário, você pode matar a chamadasubstr
e o script será executado em qualquer posix awk.