
Tenho que extrair a exceção e o rastreamento de pilha correspondente a partir de um número de linha em um arquivo de log. Eu conheço a linha de partida, não do erro. como posso descobrir onde o rastreamento de pilha terminará no exemplo abaixo? Agradeço sua ajuda
exemplo ------- 07-10-2016 15:49:07.537 ERRO Alguma exceção linha 1 do stacktrace linha 2 do stacktrace . . linha stacktrace f 07-10-2016 15:49:07.539 depurar blá blá blá 07-10-2016 15:49:07.540 depurar blá blá blá
Responder1
Para resumir, você deseja imprimir linhas começando com o número da linha especificado e continuando até pouco antes da primeira linha seguinte que começa com uma data. No seu exemplo, a linha inicial é 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 maneira:
if (NR==3)f=1
No número da linha que você especificar, defina a variável
f
como um.else if (/^[0-9-]{10} /)f=0
Em outras linhas, defina
f
como zero se a linha começar com 10 caracteres que sejam dígitos ou travessões seguidos de um espaço. Em outras palavras, definaf
como zero a primeira linha que começa com algo que se parece com 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 que se pareça com um dado, seguido por um espaço, seguido por algo que se pareça com 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 são possíveis melhorias adicionais neste aspecto.
f{print}
Se
f
for diferente de zero, imprima a linha.Para resumir, poderíamos substituir
f{print}
por apenasf
. Isto é 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 for esse o caso no 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
Responder2
Supondo que todas as linhas de rastreamento de pilha comecem com um espaço em branco (espaço/tabulação), você pode combiná-las ( [[:blank:]]
) no início da linha ( ^
):
grep '^[[:blank:]]' file.log
Responder3
Se o rastreamento que você deseja extrair começa na linha 2 de trace.log
e seu final é indicado por uma linha que começa com uma data no formato AAAA-MM-DD (e não existem tais linhas com o rastreamento), então
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log
imprimirá todas as linhas da linha 2atravéslinhan+3 (a primeira linha após o traço que começa com uma data). Como você não deseja a última linha, canalize o texto acima em um comando que remova a última linha:
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | head -n -1
ou
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | sed '$d'
Se você precisar procurar uma datae um tempoe procure por
^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}