Comment afficher les lignes après chaque correspondance de grep jusqu'à une autre correspondance spécifique?

45

Je sais qu’en utilisant le "-A NUM"commutateur, je peux imprimer un nombre spécifique de lignes de fuite après chaque match. Je me demande simplement s'il est possible d'imprimer des lignes de fin jusqu'à ce qu'un mot spécifique soit trouvé après chaque correspondance. Par exemple, lorsque je recherche "Word A", je souhaite voir la ligne contenant "Word A" ainsi que les lignes suivantes jusqu'à celle contenant "Word D".

le contexte:

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

commander:

grep -A10 'Word A'

J'ai besoin de cette sortie:

Word A
Word B
Word C
Word D
Meysam
la source

Réponses:

75

Il semble que vous souhaitiez imprimer des lignes entre ' Word A' et ' Word D' (inclus). Je vous suggère d'utiliser sedau lieu de grep. Il vous permet d'éditer une plage de flux d'entrée qui commence et se termine avec les motifs de votre choix. Vous devriez juste dire sedd'imprimer toutes les lignes de la plage et pas d'autres lignes:

sed -n -e '/Word A/,/Word D/ p' file
Saeedn
la source
Des conseils sur la façon de le rendre exclusif (pour toute situation générique, pas seulement pour les OP)?
2rs2ts
5
@ 2rs2ts pour le rendre exclusif, il suffit d'ajouter | sed -e '1d;$d', qui est supprimer la première et dernière ligne
holroy
Et si vous voulez exclure toutes les lignes entre (c’est-à-dire que vous voulez seulement voir les lignes qui se trouvent en dehors des deux correspondances), alors: sed -n -e '/pattern A/,/pattern D/d; p'Ceci dit: "Supprimez du motif A au motif D et imprimez tout le reste". Malheureusement, ce match est gourmand. Cela signifie que si les motifs A et D apparaissent plusieurs fois, vous ferez correspondre le premier motif A au dernier motif D. Je crains que Perl ou Python ne soient vos amis, si c'est le cas.
fbicknel
16

pourquoi ne pas utiliser awk?

awk '/Word A/,/Word D/' filename
cesar
la source
2
sed semble être capable de le faire beaucoup plus efficacement si un grand nombre de fichiers sont impliqués. awk est peut-être plus facile à retenir, mais sed semble valoir une note collante dans mon cerveau.
JimNim
1
awk est supérieur si Word Dtombe sur la même ligne que Word A, et peut-être ailleurs, par exemple, Word A Word D\nWord Davec sed affichera deux lignes où awk en indiquera une. De plus, on peut toujours utiliser des variables avec awk, par exemple awk -v _word="Word A" '$0 ~ _word,/Word D/' "/some/file", sed est peut-être plus efficace, mais pour les recherches sur deux chaînes pouvant tomber ou non sur la même ligne, awk sera certainement plus fiable.
S0AndS0
il semble que awk mieux gère le cas que le fichier contient des séquences de Aet Bet que vous voulez pour capturer ce qui est entre chacune de ces séquences. il semble que sed ne suive pas cette sémantique, du moins dans mon cas.
Matan
9
perl -lne 'print if /Word A/ .. /Word D/' file

ou

cat file | perl -lne 'print if /Word A/ .. /Word D/'
vinien
la source
1
+1 pour contrer le vote par abaissement. Je l'utilise quand même sed, sauf si vous avez besoin de la puissance des expressions régulières Perl pour sélectionner les lignes de délimitation.
triplee
Les personnes qui ont écrit sed dans les années 70 doivent être reconnaissantes :-)
Matan