Como grep linhas entre o padrão inicial e final? [duplicado]

14

Eu tenho um arquivo com o seguinte conteúdo:

zdk
aaa
b12
cdn
dke
kdn

Entrada1: aaa e cdn

Resultado 1:

aaa
b12
cdn

Entrada 2: zdk e dke

Resultado 2:

zdk
aaa
b12
cdn
dke

Eu poderia usar os comandos abaixo para alcançar:

grep -a aaa -A2 file # Output 1
grep -a aaa -A4 file # Output 2

Mas no arquivo não sei qual é a ocorrência exata (posição) do padrão de sequência de caracteres final (o arquivo está tendo 20000 linhas)

Como posso conseguir isso?

    
por Spike 16.10.2015 / 23:56

3 respostas

19

grep não o ajudará aqui. Este é um trabalho melhor realizado com sed usando expressões de intervalo:

$ sed -n '/aaa/,/cdn/p' file
aaa
b12
cdn
$ sed -n '/zdk/,/dke/p' file
zdk
aaa
b12
cdn
dke

sed -n suprime a impressão automática, para que as linhas sejam impressas apenas se explicitamente solicitado. E isso acontece quando o intervalo /aaa/,/cdn/ acontece.

Estas expressões de intervalo também estão disponíveis em awk , onde você pode dizer:

awk '/zdk/,/dke/' file

Naturalmente, todas essas condições podem ser expandidas para um regex mais restrito, como sed -n '/^aaa$/,/^cdn$/p' file , para verificar se as linhas consistem exatamente em aaa e cdn , nada mais.

    
por 17.10.2015 / 00:05
3

Isso pode ser feito por sed

sed -n '
    /^aaa$/,/^cdn$/w output1
    /^zdk$/,/^dke$/w output2
    ' file
    
por 17.10.2015 / 00:08
1

Aqui está o comando grep :

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

Você pode alcançar a correspondência de múltiplas linhas em grep , mas precisa usar perl-regexp para grep ( -P - que não é suportado em todas as plataformas, como o OS X). novas linhas com caractere _ e depois de grep , vamos alterá-las de volta.

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

Ou use ex :

ex +"/aaa/,/cdn/p" -scq! file
    
por 17.10.2015 / 00:23