Para resumir, você deseja imprimir linhas começando com o número da linha que você especificou e continuando até pouco antes da primeira linha seguinte que começa com uma data. No seu exemplo, a linha de partida é 3. Nesse caso:
$ awk '{if (NR==3)f=1; else if (/^[0-9-]{10} /)f=0} f{print}' trace.log
2016-10-07 15:49:07,537 ERROR Some exception
stacktrace line 1
stacktrace line 2
.
.
stacktrace line n
O código acima funciona da seguinte forma:
-
if (NR==3)f=1
No número da linha que você especificar, defina a variável
f
para um. -
else if (/^[0-9-]{10} /)f=0
Em outras linhas, defina
f
para zero se a linha começar com 10 caracteres que são dígitos ou traços seguidos por um espaço. Em outras palavras, definaf
para zero na primeira linha que começa com algo que parece uma data.Se necessário, podemos usar regexes mais complexas para identificar o início de uma data. Por exemplo, o seguinte requer que a linha comece com algo parecido com um dado, seguido por um espaço, seguido por algo que pareça tempo, seguido por uma vírgula.
awk '{if (NR==3)f=1; else if (/^[0-9-]{10} [0-9:]{8},/)f=0} f{print}' trace.log
Ainda é possível melhorar ainda mais isso.
-
f{print}
Se
f
for diferente de zero, imprima a linha.Por questões de brevidade, poderíamos substituir
f{print}
por apenasf
. Isso é possível porque, quando uma ação não é especificada explicitamente, a ação padrão deprint
é usada.
Alternativa
Algumas versões do awk não suportam fatores de repetição como {10}
. Se esse for o caso do seu sistema, tente:
awk '{if (NR==3)f=1; else if (/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] /)f=0} f{print}' trace.log