comando para extraer datos entre 2 filas

comando para extraer datos entre 2 filas

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 fen uno.

  • else if (/^[0-9-]{10} /)f=0

    En otras líneas, configúrelo fen cero si la línea comienza con 10 caracteres que son dígitos o guiones seguidos de un espacio. En otras palabras, establezca fen 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 fes distinto de cero, imprima la línea.

    Por brevedad, podríamos reemplazarlo f{print}con solo f. Esto es posible porque, cuando una acción no se especifica explícitamente, printse 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.logy 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}

información relacionada