
Tengo que extraer la excepción y el seguimiento de la pila correspondiente a partir de un número de línea en un archivo de registro. Conozco el número de línea de salida del error. ¿Cómo puedo saber dónde terminará el seguimiento de la pila en el siguiente ejemplo? Aprecio tu ayuda
ejemplo ------- 2016-10-07 15:49:07,537 ERROR Alguna excepción línea de seguimiento de pila 1 línea de seguimiento de pila 2 . . línea de seguimiento de pila sustantivo, femenino— 2016-10-07 15:49:07,539 depuración bla, bla, bla 2016-10-07 15:49:07,540 depuración bla, bla, bla
Respuesta1
En resumen, desea imprimir líneas que comiencen con el número de línea que especifique y continúen hasta justo antes de la primera línea siguiente que comience con una fecha. En su ejemplo, la línea inicial es 3. En ese 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
El código anterior funciona de la siguiente manera:
if (NR==3)f=1
En el número de línea que especifique, establezca la variable
f
en uno.else if (/^[0-9-]{10} /)f=0
En otras líneas, configúrelo
f
en cero si la línea comienza con 10 caracteres que son dígitos o guiones seguidos de un espacio. En otras palabras, establezcaf
en cero la primera línea que comience con algo que parezca una fecha.Si es necesario, podemos utilizar expresiones regulares más complejas para identificar el inicio de una fecha. Por ejemplo, lo siguiente requiere que la línea comience con algo que parezca un dato, seguido de un espacio, seguido de algo que parezca una hora, seguido de una coma.
awk '{if (NR==3)f=1; else if (/^[0-9-]{10} [0-9:]{8},/)f=0} f{print}' trace.log
Aún son posibles más mejoras a este respecto.
f{print}
Si
f
es distinto de cero, imprima la línea.Por brevedad, podríamos reemplazarlo
f{print}
con solof
. Esto es posible porque, cuando una acción no se especifica explícitamente,print
se utiliza la acción predeterminada de.
Alternativa
Algunas versiones de awk no admiten factores de repetición como {10}
. Si ese es el caso en su sistema, intente:
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
Respuesta2
Suponiendo que todas las líneas de seguimiento de la pila comienzan con un espacio en blanco (espacio/tabulación), puede hacerlas coincidir ( [[:blank:]]
) al comienzo de la línea ( ^
):
grep '^[[:blank:]]' file.log
Respuesta3
Si el seguimiento que desea extraer comienza en la línea 2 de trace.log
y su final se indica mediante una línea que comienza con una fecha en formato AAAA-MM-DD (y no existen tales líneas con el seguimiento), entonces
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log
imprimirá cada línea desde la línea 2a través delíneanorte+3 (la primera línea después del trazo que comienza con una fecha). Como no desea esa última línea, canalice lo anterior en un comando que elimine la última línea:
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | head -n -1
o
sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | sed '$d'
Si necesitas buscar una fechay un tiempo, luego busque
^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}