Combinando duas linhas diferentes que são pelo menos N linhas distantes umas das outras

2

Gostaria de fazer a correspondência de arquivos que contenham try (em uma linha) e consecutivos catch (em outra linha) pelo menos N linhas depois (para encontrar capturas muito longas e tente se livrar deles). Quero dizer, o primeiro catch após try deve ser N linhas depois.

Existe uma boa maneira de fazer isso com ferramentas padrão do UNIX, como grep , sed , awk ?

Eu experimentei fazer duas vezes grep -A <number> -B <number> , mas é bom no reverso, ou seja, encontrar os try-catches que não são mais do que N linhas.

    
por jakub.g 09.12.2013 / 14:45

1 resposta

4

E essa solução?

awk -v gap=5 '
       /try/ {inside=1; a=0; next}
       inside{a++}
      /catch/ && inside && (a>=gap) {print "line",NR, "gap of",a,$0; inside=0}
' file

Explicação

  • -v gap=5 fornece o tamanho do intervalo. Se houver algum try / catch cujas linhas estejam a uma distância maior que isso, elas serão impressas.
  • /try/ {inside=1; a=0; next} se a linha contiver um try , o contador começa. inside é o sinalizador que significa que estamos verificando um try/catch . a é o contador de linhas.
  • inside{a++} se estivermos dentro, + + o contador enquanto estiver lendo uma linha.
  • /catch/ && inside && (a>gap) se a linha contiver um "catch" e estivermos dentro da condição "try" e o contador for maior do que o que definimos com gap , em seguida, {print "line",NR, "gap of",a,$0; inside=0} .

Teste

$ cat a
hello
try
line1
catch

blabla
try
line1
line2
line3
line4
catch
end

Com um intervalo de 5:

$ awk -v gap=5 '/try/ {inside=1; a=0; next} inside{a++} /catch/ && inside && (a>=gap) {print "line",NR, "gap of",a,$0; inside=0}' a
line 12 gap of 5 catch

Com um intervalo de 2:

$ awk -v gap=2 '/try/ {inside=1; a=0; next} inside{a++} /catch/ && inside && (a>=gap) {print "line",NR, "gap of",a,$0; inside=0}' a
line 4 gap of 2 catch
line 12 gap of 5 catch
    
por 09.12.2013 / 15:12

Tags