Imprima linhas entre (e incluindo) dois padrões

13

Eu quero começar a usar as linhas que tem CK no final da linha e parar o grepping quando a linha tiver D no final. Eu tentei grep "$CK" "$D" file..txt , mas não funcionou.

Entrada:

kkkkkkkkkkk   
jjjjjjjjjjjjjjjjjj  
gggggggggggg/CK  
JHGHHHHHHHH   
HJKHKKLKLLL   
JNBHBHJKJJLKKL  
JLKKKLLKJLKJ/D  
GGGGGGGGGGGGGG  
GGGGGGGGGGGGGG

A saída desejada:

gggggggggggg/CK  
JHGHHHHHHHH   
HJKHKKLKLLL   
JNBHBHJKJJLKKL  
JLKKKLLKJLKJ/D
    
por Rana Khan 08.11.2013 / 18:28

2 respostas

18

É melhor usar ou

awk '/CK$/,/D$/' file.txt

OR

sed -n '/CK$/,/D$/p' file.txt

Se você insistir em , aqui está uma maneira do GNU grep

grep -oPz '(?s)(?<=\n)\N+CK\n.*?D(?=\n)' file.txt

aqui

-P ativa perl-regexp

-z define o separador de linha como NUL. Isso força o grep a ver o arquivo inteiro como uma única linha

-o imprime apenas correspondência

(?s) ativa PCRE_DOTALL, então . encontra qualquer caractere ou nova linha

\N corresponde a qualquer coisa, exceto nova linha

.*? encontra. no modo nongreedy

(?<=..) é uma afirmação com olhar para trás

(?=..) é uma afirmação antecipada

    
por 08.11.2013 / 18:31
0

Se você estiver usando BSD grep (não suporta perl regex param -P ), aqui está a solução alternativa:

grep -o "aaa.*cdn" <(paste -sd_ file) | tr '_' '\n'

Isso funciona concatenando todas as linhas (substituindo novas linhas por _ character), verificando o padrão de uma linha e expandindo as linhas de volta ao seu estado original.

Se você estiver usando o GNU grep , poderá obter correspondência de múltiplas linhas em grep , mas precisará usar perl-regexp para grep ( -P ), como mencionado em outro responder . Você ainda pode instalar o GNU grep no macOS via brew install grep e usar ggrep .

Como alternativa, você pode usar pcregrep que suporta padrões de várias linhas ( -M ).

Você também pode usar o comando ex , por exemplo:

ex +"/aaa/;/cdn/p" -scq! file
    
por 22.12.2016 / 14:43