Eu abordaria isso armazenando as linhas da mensagem atual e, quando a mensagem terminar, imprimindo o lote armazenado, se não houver nenhum marcador INF
visto. Aqui, d
contém as linhas da mensagem atual (d para dados), p
informa se queremos imprimir as linhas armazenadas ou não.
awk -vinfo='INF99+' \
'/^20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]/ {
if (p) printf "%s", d; d = $0 ORS; p=1; next }
$0 ~ info {p=0}
{d = d $0 ORS}
END {if (p) printf "%s", d}' < log
A primeira regra aqui corresponde às linhas de timestamp, imprime todas as linhas armazenadas se p
for true, armazena essa linha e define p
para uma.
A segunda regra redefine p
para zero se uma linha com o padrão info
for vista; o padrão é definido para a variável com -vinfo=...
.
A terceira regra anexa a linha atual às coletadas, e a regra END
apenas imprime as linhas coletadas se p
estiver definido.
Também poderíamos escrevê-lo assim, isso verificaria o padrão info
também na linha de timestamp:
awk -vinfo='INF99+' \
'/^20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]/ {
if (p) { printf "%s", d }; d = ""; p=1; }
$0 ~ info {p=0}
{d = d $0 ORS}
END {if (p) printf "%s", d}' < log
Em geral, é provavelmente uma boa ideia escrever coisas como esta em awk
ou Perl. O resultado será, no mínimo, muito mais rápido de executar do que um script de shell que bifurca dezenas de cópias de grep
, awk
e cut
etc ...