Usando grep / sed / awk para classificar as entradas do arquivo de log

4

Eu preciso processar um arquivo de log muito grande com muitas linhas em diferentes formatos.

Meu objetivo é extrair entradas de linha exclusivas que tenham o mesmo padrão inicial, por exemplo, '^ 2011-02-21. * MyKeyword. * Error', obtendo efetivamente uma lista de amostras para cada padrão de linha, portanto identificando os padrões.

Eu só conheço alguns padrões até agora, e navegar pelo arquivo manualmente definitivamente não é a opção.

Por favor, note que além dos padrões conhecidos, há vários outros desconhecidos, e eu gostaria de automatizar a extração desses padrões também.

Qual é a melhor maneira de fazer isso? Eu sei expressões regulares muito bem, mas não fiz muito trabalho com o awk / sed que imagino que seria usado em algum ponto deste processo.

    
por Jas 21.02.2011 / 21:21

2 respostas

2

Se eu entendi corretamente, você tem vários padrões e deseja extrair uma correspondência por padrão. O seguinte script awk deve fazer o truque. Ele imprime a primeira ocorrência do padrão especificado e registra que o padrão foi visto de forma a não imprimir ocorrências subseqüentes.

awk '
/^2011-02-21.*MyKeyword.*Error/ {
    if (!seen["^2011-02-21.*MyKeyword.*Error"]++) print;
    next;
}
1 {if (!seen[""]++) print}  # also print the first line that matches no pattern
'

Aqui está uma variante que mantém uma linha MyKeyword.*Error por dia.

awk '
/^[0-9]{4}-[0-9]{2}-[0-9]{2}.*MyKeyword.*Error/ {
    if (!seen[substr($0,10) "MyKeyword.*Error"]++) print;
    next;
}
'
    
por 21.02.2011 / 21:33
1

Não está claro se você está tentando agrupar linhas por padrões de saída desconhecidos ou palavras-chave desconhecidas em padrões conhecidos.

No primeiro caso, se você tiver registros como:

[2010-04-02 12:00:00] Error: BaseController Something went wrong
2010-04-02 12:01:00 Warning - Something happened
UserController (2010-04-02 12:02:00) failed with exit status: 1
[2010-04-02 12:03:00] Error: BaseController Something went wrong
[2010-04-02 12:04:00] Error: BaseController Something went wrong
2010-04-02 12:04:01 Warning - Something else happened
UserController (2010-04-02 12:05:00) failed with exit status: 2
UserController (2010-04-02 12:06:00) failed with exit status: 10

você pode usar tr e sort e / ou uniq para explorar os padrões:

$ tr '[:alpha:]' x < file.log | tr '[:digit:]' d | sort -u

dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxxxxxx
dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxx xxxxxxxx
[dddd-dd-dd dd:dd:dd] xxxxx: xxxxxxxxxxxxxx xxxxxxxxx xxxx xxxxx
xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: d
xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: dd

ou, se você quiser contar ocorrências:

$ tr '[:alpha:]' x < file.log | tr '[:digit:]' d | sort | uniq -c
      1 
      1 dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxxxxxx
      1 dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxx xxxxxxxx
      3 [dddd-dd-dd dd:dd:dd] xxxxx: xxxxxxxxxxxxxx xxxxxxxxx xxxx xxxxx
      2 xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: d
      1 xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: dd

Mas se o padrão é sempre o mesmo, como MyKeyword está sempre no mesmo lugar (como [2010-04-02 12:00:00] Error: BaseController Something went wrong ), mas você quer descobrir quais strings podem estar nessa posição, simplesmente:

$ awk '{a[$3]++} END {for (i in a) {printf("%4d %s\n", a[i], i) } }' file.log

que deve lhe dar algo parecido com

   3 Error
   1 Info
   2 Warning
    
por 14.04.2014 / 09:01