exibe o conteúdo do arquivo de algum padrão de múltiplas linhas até o final

0

Como posso exibir o conteúdo do arquivo de um padrão de várias linhas até o final incluindo o próprio padrão ?

Eu fiz uma pergunta semelhante agora, mas é diferente e eu pensei que deveria postar isso como uma nova pergunta separada. Então, por favor, não marque esta duplicata simplesmente por causa disso!

Por exemplo, se eu tivesse um arquivo de texto como este:

cat
dog
fox
cow
dove
bird
bunny
gnu
hen
dove
bird
buffalo

e se meu padrão fosse este:

dove
bird
bunny

o que eu gostaria de obter seria:

dove
bird
bunny
gnu
hen
dove
bird
buffalo

Meu arquivo real é enorme, por isso, se houver várias maneiras de conseguir isso, prefiro maneiras mais rápidas.

    
por stacko 21.06.2017 / 20:18

3 respostas

0

Se você quiser imprimir a partir da primeira vez que o padrão aparecer, será fácil. Siga a mesma lógica que descrevi na outra resposta , mas com alguma lógica extra:

parse.sed

/^dove$/ {            # Match multi-line pattern
  N                   #  /
  N                   # /
  /\nbird\nbunny$/bb  # When matched jump to label b
}
d                     # Restart with next line if no match
:b                    # \
n                     #  Print the rest of the file
bb                    # /

Execute assim:

sed -f parse.sed infile

Ou como um one-liner portátil:

sed -n -e '/^dove$/{N;N;/\nbird\nbunny$/bb' -e '};d;:b' -e 'p;n;bb' infile

A saída nos dois casos:

dove
bird
bunny
gnu
hen
dove
bird
buffalo
    
por 21.06.2017 / 21:59
0

Aqui está uma solução Perl:

perl -0777 -ne 'print $1,$2 if m/(dove.bird.bunny)(.*)/sm' myfile

Esta saída:

dove
bird
bunny
gnu
hen
dove
bird
buffalo

A opção -0777 ativa o modo slurp que lê todo o arquivo na memória. o uso de modificadores sm na correspondência permite que um ponto corresponda a uma nova linha enquanto trata a sequência como várias linhas.

A opção -n cria um loop de leitura para o arquivo de entrada. Quando a sequência dove.bind.bunny é vista, ela é capturada em $1 com as linhas restantes em $2 e é o que é impresso se a correspondência geral for bem-sucedida.

    
por 21.06.2017 / 22:43
0
Solução

awk :

awk -v RS=" " '{                        # considering space as record separator
                  for(i=1;i<=NF;i++) {  # iterating through all fields
                     if ($i=="dove" && $(i+1)=="bird" && $(i+2)=="bunny") { f=1 } 
                     if (f) print $i 
                  } 
               }' file

A saída:

dove
bird
bunny
gnu
hen
dove
bird
buffalo
    
por 21.06.2017 / 22:43