Script de shell para contar apenas dias consecutivos

1

Eu queria saber como eu poderia fazer isso.

Este é um exemplo da minha saída

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

Agora, o que eu gostaria de fazer é contar apenas consecutivos dias. No exemplo acima, deve-se dizer que BLAH apareceu três vezes, uma após a outra.

Eu tenho o bash, o awk e o sed disponíveis.

    
por Rodrigues R 25.08.2016 / 21:19

2 respostas

1

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 chamada substr e o script será executado em qualquer posix awk.
por 26.08.2016 / 01:25
0

Isso levou mais do que eu pensava, mas o roteiro abaixo fará o trabalho.

#!/bin/bash
str=" Sun Aug 21 2016 03:00:00, BLAH Mon Aug 22 2016 03:54:00, BLAH"
str+=" Tue Aug 23 2016 04:22:11, BLAH Thu Aug 25 2016 05:00:00, BLAH"
IFS='H' read -r -a inputArray <<< "$str"
days=(SunMon MonTue TueWed WedThu ThuFri FriSat SatSun)
count=1
found=0
lastOne=""
finalCount=0
for entry in "${inputArray[@]}"; do
   thisOne="${entry:1:3}"
   test="$lastOne$thisOne"
   for pair in "${days[@]}"; do
      if [ "$test" == "$pair" ]; then
         ((++count, ++found))
      fi
   done
   if [ ! $found ]; then count=1; else found=0; fi
   if [ $count -gt $finalCount ]; then
      finalCount=$count
   fi
   lastOne=$thisOne
done
echo "There were $finalCount BLAHs in a row."
    
por 26.08.2016 / 01:10