Filtrar linhas entre strings correspondentes

Filtrar linhas entre strings correspondentes

Tenha um conteúdo no arquivo semelhante ao abaixo - Existem muitas linhas entre START e END e também podem conter erros/avisos. Quero filtrar erros/linhas de aviso entre START e END e pular se não houver. O título varia com nomes diferentes. Mas faça a lógica de imprimir a próxima linha de START (deveria ser o título)

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

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

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

Resultado esperado abaixo

Heading1
errors

Heading3
errors
Warning...

Eu tentei abaixo, mas isso imprime tudo entre START e END. Eu tenho que filtrar erros também

awk '/START/,/END/' file

Responder1

Tentar:

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

Como funciona

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

    Se ffor verdadeiro (diferente de zero), salve a linha atual na variável hdge fvolte a zero.

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

    Se a linha atual contiver errorsou warning, então, se a variável hdgnão estiver vazia, imprima-a. Além disso, imprima a linha atual.

  • /START/{f=1}

    Se a linha atual contiver START, defina a variável fcomo um.

Versão multilinha

Para quem prefere seus comandos espalhados por várias linhas:

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

Variação: adicione uma linha em branco antes do título

Se quisermos uma linha em branco para separar a saída:

$ 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

Variação: Ignore erros/avisos após uma linha END

$ 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 tornar o caso acima insensível (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

informação relacionada