Supondo que seu arquivo de log é chamado logfile
, aqui está uma solução awk
com a saída de exemplo:
$ awk '/RINGING/,/CLOSE/ {if (/30 30/){f=1}; a=a"\n"$0} f==0 && /CLOSE/ {print a} /CLOSE/{a="";f=0}' logfile
313782 Aug 19 18:37:04.925: <DATA> RINGING|254|01136097645|5950|$hostIp|$size |$data
313783 Aug 19 18:37:05.262: <DATA> TRAINING|254|01136097645|5950|$hostIp|$size |$data
313784 Aug 19 18:37:09.028: <DATA> OUT |254|01136097645|5950|$hostIp|2 bytes |30 93
313785 Aug 19 18:37:09.705: <DATA> IN |254|01136097645|5950|$hostIp|4 bytes |30 73 F9 F8
313786 Aug 19 18:37:18.532: <DATA> IN |254|01136097645|5950|$hostIp|336 bytes |30 10 60 00 06 00 00 6F 12 00
313788 Aug 19 18:37:20.898: <DATA> TRAINING|254|01136097645|5950|$hostIp|$size |$data
313789 Aug 19 18:37:22.006: <DATA> CLOSE|254|01136097645|5950|$hostIp|$size |$data
Explicação
Tomando cada comando awk
por vez:
-
/RINGING/,/CLOSE/ {if (/30 30/){f=1}; a=a"\n"$0}
A expressão
/RINGING/,/CLOSE/
é um intervalo: especifica que este comando se aplica apenas a grupos de linhas. Um grupo é iniciado quando é encontrada uma linha que inclui o textoRINGING
. O grupo termina quando uma linha que inclui o textoCLOSE
é encontrada. Para qualquer linha desse grupo, os comandos entre chaves são executados. O primeiro deles define o sinalizadorf
para um se a linha contiver30 30
. O segundo comando acrescenta a linha atual à variávela
. -
f==0 && /CLOSE/ {print a}
Os comandos entre chaves são precedidos por duas condições e juntos. A primeira condição especifica que o sinalizador
f
é zero (significando que30 30
não foi encontrado neste grupo) e o segundo especifica que essa linha contém o textoCLOSE
. Se ambas as condições forem atendidas, o grupo de linhas, armazenado na variávela
, será impresso. -
/CLOSE/{a="";f=0}
Por último, em qualquer linha que contenha o texto
CLOSE
, a variávela
será redefinida para a sequência vazia e o sinalizadorf
será definido como zero. Quando isso é feito, o código é preparado para iniciar no próximo grupo de linhas, se houver um.