Como faço para grep para múltiplos padrões em múltiplas linhas?

1

Para ser preciso

Some text
begin
Some text goes here.
end
Some more text

e eu quero extrair todo o bloco que começa de "begin" até "end"

com awk podemos fazer como

awk '/begin/,/end/' text

como fazer com grep ? Existem implementações de grep em algum * nix com o qual isso pode ser feito?

    
por Iker 19.11.2014 / 10:30

1 resposta

6

grep , que é g/re/p , é uma ferramenta básica para p alterar as linhas que correspondem a uma xpressão egb e .

Você quer mais aqui, como um s tream ed ou:

sed '/^begin$/,/^end$/!d'

ou uma ferramenta de processamento de texto mais geral com uma linguagem avançada como awk , perl ... como você já descobriu.

Dito isto, algumas implementações grep podem ir um pouco mais longe.

pcregrep -M '(?s)^begin$.*?^end$'

Isso está usando o modo multi-line ( -M ); (?s) alterna o sinalizador s no regexp do PCRE, de forma que . também corresponda aos caracteres da nova linha.

Com a versão atual de pcregrep , não é garantido que funcione se begin e end forem mais do que 20kiB separados (ou o tamanho do buffer especificado).

Por exemplo, será igual a

(seq 12091; echo begin; seq 4315; echo end; seq 10) |
   pcregrep -M '(?s)^begin$.*?^end$'

Mas não em:

(seq 12091; echo begin; seq 4316; echo end; seq 10) |
   pcregrep -M '(?s)^begin$.*?^end$'

Ou com o GNU grep construído com suporte a PCRE e assumindo que o arquivo não contenha caracteres NUL:

grep -zoP  '(?s)^begin$.*?^end$'

No entanto, isso significa que grep carregará o arquivo inteiro na memória antes de iniciar a pesquisa, portanto, não deve ser usado, exceto para arquivos pequenos.

De qualquer forma, grep não é o caminho certo para ir até aqui.

    
por 19.11.2014 / 11:44

Tags