Filtrar líneas entre cadenas coincidentes

Filtrar líneas entre cadenas coincidentes

Tenga un contenido en el archivo similar al siguiente: hay muchas líneas entre INICIO y FIN y también pueden tener errores/advertencias. Quiero filtrar errores/líneas de advertencia entre INICIO y FIN y omitirlos si no es así. El título varía con diferentes nombres. Pero haga que sea lógico imprimir la siguiente línea de INICIO (debería estar encabezada)

START
Heading1
.......
errors
........
END

START
Heading2
........
........
........
END

START
Heading3
.......
errors
Warning...
END

Salida esperada a continuación

Heading1
errors

Heading3
errors
Warning...

Lo he intentado a continuación, pero esto imprime todo entre INICIO y FINAL. También tengo que filtrar errores.

awk '/START/,/END/' file

Respuesta1

Intentar:

$ awk 'f{hdg=$0; f=0} /errors|warning/{if(hdg){print hdg; hdg=""}; print} /START/{f=1}' file
Heading1
errors
Heading3
errors

Cómo funciona

  • f{hdg=$0; f=0}

    Si fes verdadero (distinto de cero), guarde la línea actual en la variable hdgy fvuelva a establecerla en cero.

  • /errors|warning/{if(hdg){print hdg; hdg=""}; print}

    Si la línea actual contiene errorso warning, entonces, si la variable hdgno está vacía, imprímala. Además, imprima la línea actual.

  • /START/{f=1}

    Si la línea actual contiene START, establezca la variable fen uno.

Versión multilínea

Para aquellos que prefieren que sus comandos se distribuyan en varias líneas:

awk '
   f {
      hdg=$0
      f=0
   }
   /errors|warning/{
      if(hdg){
         print hdg
         hdg=""
      }
      print
   }
   /START/{
      f=1
   }' file

Variación: agregue una línea en blanco antes del encabezado

Si queremos una línea en blanco para separar la salida:

$ awk 'f{hdg=$0; f=0} /errors|warning/{if(hdg){print nl hdg; hdg=""; nl="\n"}; print} /START/{f=1}' file
Heading1
errors

Heading3
errors

Variación: ignorar errores/advertencias después de una línea FINAL

$ awk 'f{hdg=$0; f=0} g && /errors|warning/{if(hdg){print nl hdg; hdg=""; nl="\n"}; print} /START/{f=1; g=1} /END/{g=0}' file
Heading1
errors

Heading3
errors

Para que lo anterior no distinga entre mayúsculas y minúsculas (GNU awk):

awk 'BEGIN{IGNORECASE=1} f{hdg=$0; f=0} g && /errors|warning/{if(hdg){print nl hdg; hdg=""; nl="\n"}; print} /START/{f=1; g=1} /END/{g=0}' file

información relacionada