Extrair com grep / sed um primeiro padrão e, em seguida, um segundo padrão que ocorreu algumas linhas antes e relacionadas ao primeiro

0

Estou tentando extrair uma linha específica de um arquivo .htm quando um padrão ocorre ("Evento 100" no meu exemplo abaixo), mas ao mesmo tempo preciso recuperar outro padrão relacionado ao primeiro mas que vem de uma das linhas acima dela. Este segundo padrão representa o tempo em que o primeiro padrão ocorreu:

Exemplo:

<AZ>207994</AZ>
<AZ>09:10:41.9</AZ>
<AZ>02/04</AZ>
<AZ>[990875]</AZ>
<TR VALIGN=TOP>
<AZ>207995</AZ>
<AZ>09:10:56.4</AZ>
<AZ>02/04</AZ>
<AZ>[990876]</AZ>
<AZ>30718</AZ><AZ><!--void--></AZ><AZ><!--void--></AZ><AZ><!--void--></AZ>
<AZ>TN (speed)  Event 3 occurred</TD></TR>
<TR VALIGN=TOP>
<AZ>30719</TD><TD><!--void--></AZ><AZ><!--void--></AZ><AZ><!--void--></AZ>
<AZ>TN (speed)  Event 100 occurred</TD></TR>
<TR VALIGN=TOP>
<AZ>30720</AZ><AZ><!--void--></AZ><AZ><!--void--></AZ><AZ><!--void--></AZ>

Eu quero o seguinte resultado:

02/04 09: 10: 56.4 [990876] Ocorreu o evento 100

    
por John 08.04.2014 / 09:46

2 respostas

2

Eu inventei este oneliner desagradável (quebras de linha para legibilidade):

awk -F'[<>]'  '($0 ~ /[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/) {time=$3}
               ($0 ~ /[0-9][0-9]\/[0-9][0-9]/) {date=$3}
               ($0 ~ /\[[0-9]+\]/) {tag=$3}
               ($0 ~ /Event 100 occurred/) { print date, time, tag, "Event 100 occurred"}' < testfile

Isso consistentemente coleta coisas que parecem uma hora, uma data ou uma tag ([12345]), e se uma linha como "Evento 100 ocorreu" ocorre, o conteúdo atual das variáveis é impresso. Essa é a saída desejada?

    
por 08.04.2014 / 10:27
0

Isso deve funcionar:

(grep -oP "Event 100" file && \
sed -ne 's/<\/\?AZ>//g' -e '7,9p' file) | \
awk 'BEGIN {RS=""; FS="\n";} \
{printf "%s %s %s %s\n", $3, $2, $4, $1}'

Explicação :

  • file : o arquivo que contém sua saída acima
  • grep -oP "Event 100" file : pesquisa por "evento 100"
  • sed -ne 's/<\/\?AZ>//g' -e '7,9p' file : Se a string foi encontrada, remova as tags <AZ> e </AZ> e imprima as linhas 7 a 9
  • awk 'BEGIN {RS=""; FS="\n";} : defina o sepatator de campo do awk como nova linha
  • {printf "%s %s %s %s\n", $3, $2, $4, $1} : e imprima a saída na ordem desejada

Saída (se a string for encontrada):

02/04 09:10:56.4 [990876] Event 100

Se a string não for encontrada, não haverá saída.

    
por 08.04.2014 / 10:41

Tags