grep um arquivo de log começando do horário específico até o final do arquivo

3

Eu tenho um arquivo de log que tem uma data e hora no início de cada linha.

Eu preciso pesquisar o arquivo de log começando de um horário específico até o final do arquivo.

Por exemplo:

Starting point: July 29 2018 21:00:00
End point     : end of file

Minha preocupação é que, mesmo que o padrão de July 29 2018 21:00:00 não exista, ainda recebo as linhas entre, por exemplo, July 29 2018 21:05:11 , pois isso ainda está além de July 29 2018 21:00:00 .

awk ou sed funciona para isso?

    
por megaman 14.08.2018 / 11:54

4 respostas

2

Eu usaria perl para isso, para analisar o timestamp em cada linha:

$ cat file
June 5 2018 00:00:00 do not print
July 29 2018 20:59:59 do not print
July 29 2018 21:00:00 print me
July 29 2018 21:00:01 print me

$ perl -MTime::Piece -sane '
    BEGIN {
        $start = Time::Piece->strptime($startdate, "%B %e %Y %T");
    }
    # the string "@F[0..3]" is the first 4 words on the line
    $time = Time::Piece->strptime("@F[0..3]", "%B %e %Y %T");
    print if $time >= $start;
' -- -startdate="July 29 2018 21:00:00" file
  
July 29 2018 21:00:00 print me
July 29 2018 21:00:01 print me

Esta versão é um pouco mais eficiente, pois deixa de analisar o registro de data e hora depois que a data de início é vista (presume que o arquivo está aumentando a ordem cronológica):

perl -MTime::Piece -sane '
    BEGIN {
        $start = Time::Piece->strptime($startdate, "%B %e %Y %T");
    }
    unless ($go) {
        $time = Time::Piece->strptime("@F[0..3]", "%B %e %Y %T");
        $go = $time >= $start;
    }
    print if $go;
' -- -startdate="July 29 2018 21:00:00" file
    
por 14.08.2018 / 16:00
1

Tente isto:

grepfromdate() {
    readarray f < $1
    fromdate=$(date +%s -d "$2")
    for (( lineno=${#f[@]}-1 ; lineno>=0; lineno-- )) ; do
        line=${f[$lineno]}
        time_from_line=$(echo "$line" | grep -o "^[A-Z][a-z]* [0-9][0-9] [0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]")
        [[ $(date +%s -d "$time_from_line") -gt $fromdate ]] && echo "$line" || break
    done | tac
}

Usage:
grepfromdate "filename" "July 29 2018 21:00:00"

Você pode transmitir qualquer formato de data que date possa ler para ele, por exemplo, %código%. Se o formato da data mudar, você pode alterar o padrão 2018-07-01 de acordo com isso.

    
por 14.08.2018 / 16:22
0

Você pode procurar a primeira linha que corresponda a uma String definida (ou seja, July 29 2018 21: para tudo depois das 21h). Se você tiver esse número de linha, poderá tail do arquivo começar com o número da linha encontrado.

   $ man tail
   -n, --lines=[+]NUM
          output the last NUM lines, instead of the last 10; or use -n +NUM to output starting with line NUM

meu exemplo:

$ log=/var/log/syslog

# get line number
$ first_line=$(grep -no "Aug 14 08:" $log | tail -n1 | cut -d: -f1)

# count the lines from $first_line to EOF
$ tail -n +$first_line $log | wc -l
24071

# output the content starting with $first_line
$ tail -n +$first_line $log

# line count of the whole file:
$ wc -l $log
70896 /var/log/syslog
    
por 14.08.2018 / 13:37
0

Com sed você pode fazer

sed -n '/July 29 2018 21:/,/$!d/p' file

Isso vai te dar todas as linhas entre 29 de julho de 2018 21: ** e a última linha de arquivo

    
por 14.08.2018 / 14:35