Grep log e obtém texto entre os delimitadores de log

4

Existe uma maneira de grep a log e encontrar texto entre os delímetros de entrada de log? Nosso arquivo de log separa a entrada de linha com caracteres " ------- " Então, quando eu procuro a palavra de texto, eu quero todas as linhas antes e depois dos delímetros no log.

Log de amostra

------------------------------------------------------------------------

    r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines
    Removed unused "Calculated Fields" column entry.
    Jira ID: JIRA-977

------------------------------------------------------------------------

No exemplo acima, eu colocaria a palavra Grep Fields, mas quero todas as linhas entre as linhas " ---- "

    
por user3609755 12.05.2014 / 20:22

2 respostas

6

Se você souber o tamanho do registro, poderá gerar linhas de contexto adicionais antes ( -B ) e depois ( -A ) da linha correspondente, por exemplo,

grep -A2 -B2 'Fields' sample.log

ou para o contexto antes e depois da linha de jogo

grep -C3 'Fields' sample.log

Até onde eu sei, a única maneira de fazer uma verdadeira combinação de múltiplas linhas (em vez de uma única linha mais contexto) no GNU grep é usando o modo regex do PCRE ( -P ) com o -z para evitar quebrar em novas linhas. Por exemplo, você poderia tentar

grep -zPo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'

que faz uma correspondência não-gulosa da string Fields cercada por quaisquer caracteres OU novas linhas, desde que seja reservada pelos delimitadores newline-hyphens-newline . Uma expressão equivalente em pcregrep é

pcregrep -Mo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'


Outra opção para este tipo de dados estruturados em registros é o awk: em particular, o GNU awk permite que uma expressão regular seja usada para o separador de registro RS, por exemplo,

$ gawk -vRS='\n-+\n' '/Fields/ {print}' sample.log

r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines

Removed unused "Calculated Fields" column entry.

Jira ID: JIRA-977
    
por 12.05.2014 / 21:21
3

Uma solução Perl semelhante à gawk na resposta da steeldriver no caso de gawk não ser disponível:

perl -ne 'BEGIN{$/= "-"x72 . "\n"} chomp and print if /Fields/' log_file

Substitua 72 pelo número real de traços no seu delimitador.

    
por 12.05.2014 / 21:41