grep - mostra linhas até certo padrão [duplicado]

4

Estou no Ubuntu 16.04 e quero pesquisar arquivos por digamos "if" e quero a saída até "endif". O arquivo pode se parecer com isso

if …
  SOME CODE
endif

Eu posso fazer isso com grep -A9 if my_file | grep -B9 endif . Isso não funciona se a cláusula "if" for maior que 9 e se várias cláusulas "if" estiverem no mesmo arquivo e se o primeiro comando grep contiver várias cláusulas "if". A opção -m1 no segundo grep não ajuda. Cláusulas "if" aninhadas podem ser ignoradas. Tem alguém uma ideia, talvez não com o grep?

Diferença para Como eu faço para vários padrões? em várias linhas?

  1. A pergunta pede uma solução com grep , que já está respondida na pergunta: grep -A9 if my_file | grep -B9 endif . A solução não funciona no meu caso, mas funcionaria no caso da outra pergunta.

  2. As soluções grep propostas para a outra pergunta não funcionam (com o Ubuntu?): grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt. , que é algo como grep: a not protected ^ or $ is not supported with -Pz . Eu uso o seguinte:

    root:/tmp# cat file
    Some text
    begin
    Some text goes here.  
    end
    Some more text 
    root:/tmp# grep -Pzo "^begin$(.|\n)*^end$" file
    grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt
    
  3. As soluções propostas pesquisam apenas padrões que começam no início da linha se eu interpretar a solução proposta corretamente. Mesmo se eu remover ^ , o comando não funciona.

por musbach 13.11.2016 / 18:05

3 respostas

14

Você pode usar sed para isso:

sed -n '/if/,/endif/p' myfile
  • -n não imprime nada até pedirmos
  • /if/ encontra a primeira linha com esta
  • , continue até ...
  • /endif/ esta é a última linha que queremos
  • p imprime as linhas correspondentes
por Zanna 13.11.2016 / 18:07
6

Tradicional grep é orientado para linha. Para fazer correspondências com várias linhas, você precisa enganá-lo para que o arquivo inteiro seja sugado, informando que sua entrada é terminada com null, por exemplo.

grep -zPo '(?s)\nif.*\nendif' file

ou use uma ferramenta mais flexível, como pcregrep

pcregrep -M '(?s)\nif.*?\nendif' file

ou o próprio perl

perl -00 -ne 'print if m/^if.*?endif/s' file

Como alternativa, para corresponder a entrada estruturada de uma maneira semelhante ao grep, há sgrep

sgrep '"if" .. ("endif") containing "SOME CODE"' file
    
por steeldriver 13.11.2016 / 18:25
4

Uma solução awk poderia ser semelhante a: awk '/if/,/endif/' file

Naturalmente, é semelhante à solução com sed .

    
por user618061 13.11.2016 / 22:10