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=1No número da linha que você especificar, defina a variável
fpara um. -
else if (/^[0-9-]{10} /)f=0Em outras linhas, defina
fpara 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, definafpara 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.logAinda é possível melhorar ainda mais isso.
-
f{print}Se
ffor 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