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 sinalizadorfpara 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 30nã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ávelaserá redefinida para a sequência vazia e o sinalizadorfserá definido como zero. Quando isso é feito, o código é preparado para iniciar no próximo grupo de linhas, se houver um.