Como mostrar linhas após cada correspondência grep até outra correspondência específica?

45

Sei que, usando o "-A NUM"comutador, posso imprimir um número específico de linhas finais após cada correspondência. Só estou imaginando se é possível imprimir linhas finais até que uma palavra específica seja encontrada após cada correspondência. Por exemplo, quando eu procuro por "Palavra A", quero ver a linha que contém "Palavra A" e também as linhas após ela até a que contém "Palavra D".

contexto:

Word A
Word B
Word C
Word D
Word E
Word F

comando:

grep -A10 'Word A'

Eu preciso desta saída:

Word A
Word B
Word C
Word D
Meysam
fonte

Respostas:

74

Parece que você deseja imprimir linhas entre ' Word A' e ' Word D' (inclusive). Eu sugiro que você use em sedvez de grep. Permite editar um intervalo de fluxo de entrada que começa e termina com os padrões desejados. Você deve apenas dizer sedpara imprimir todas as linhas no intervalo e nenhuma outra linha:

sed -n -e '/Word A/,/Word D/ p' file
saeedn
fonte
Alguma dica de como torná-lo exclusivo (para qualquer situação genérica, não apenas para OP)?
Jun2 '
4
@ 2rs2ts para torná-lo exclusivo, basta adicionar | sed -e '1d;$d', que é remover primeira e última linha
holroy
E se você deseja excluir todas as linhas entre - ou seja, deseja ver apenas as linhas que estão fora das duas correspondências -, então: sed -n -e '/pattern A/,/pattern D/d; p'Isto diz: "exclua do padrão A para o padrão D e imprima todo o resto". Infelizmente, este jogo é ganancioso. Isso significa que se os padrões A e D aparecerem mais de uma vez, você corresponderá do primeiro padrão A ao último padrão D. Acho que Perl ou Python são seus amigos, se for o caso.
Fbicknel
16

por que não usar awk?

awk '/Word A/,/Word D/' filename
cesar
fonte
2
O sed parece conseguir fazer isso com muito mais eficiência se um grande número de arquivos estiver envolvido. awk pode ser mais fácil de lembrar, mas sed parece valer uma nota no meu cérebro.
JimNim
1
O awk é superior se Word Dcair na mesma linha que Word A, e possivelmente em outro lugar, por exemplo, Word A Word D\nWord Dcom o sed mostrará duas linhas, onde o awk mostrará uma. Além disso, ainda é possível usar variáveis ​​com o awk, por exemplo awk -v _word="Word A" '$0 ~ _word,/Word D/' "/some/file", portanto, talvez seja mais eficiente, mas ao lidar com pesquisas de duas strings que podem ou não cair na mesma linha, o awk definitivamente é mais confiável.
S0AndS0
parece que awk melhor lida com o caso que o arquivo contém seqüências de Ae Be você só quer capturar o que há entre cada tal sequência. parece que o sed não segue essas semânticas pelo menos no meu caso.
Matan
9
perl -lne 'print if /Word A/ .. /Word D/' file

ou

cat file | perl -lne 'print if /Word A/ .. /Word D/'
viniano
fonte
1
+1 para combater o voto negativo drive-by. Eu ainda usaria sedisso, a menos que você precise do poder das expressões regulares do Perl para selecionar as linhas delimitadoras.
Tripleee
As pessoas que escreveram sed nos anos 70 devem ser gratas :-)
Matan