¿Cómo mostrar líneas después de cada coincidencia grep hasta otra coincidencia específica?

45

Sé que al usar el "-A NUM"interruptor puedo imprimir un número específico de líneas finales después de cada coincidencia. Me pregunto si es posible imprimir líneas finales hasta que se encuentre una palabra específica después de cada coincidencia. Por ejemplo, cuando busco "Palabra A", quiero ver la línea que contiene "Palabra A" y también las líneas posteriores hasta la que contiene "Palabra D".

contexto:

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

mando:

grep -A10 'Word A'

Necesito esta salida:

Word A
Word B
Word C
Word D
Meysam
fuente

Respuestas:

75

Parece que desea imprimir líneas entre ' Word A' y ' Word D' (inclusive). Te sugiero que uses en sedlugar de grep. Le permite editar un rango de flujo de entrada que comienza y termina con los patrones que desee. Solo debe indicar sedque imprima todas las líneas dentro del rango y no otras líneas:

sed -n -e '/Word A/,/Word D/ p' file
saeedn
fuente
¿Algún consejo sobre cómo hacerlo exclusivo (para cualquier situación genérica, no solo de OP)?
2rs2ts
55
@ 2rs2ts para hacerlo exclusivo, solo agregue | sed -e '1d;$d', es decir, elimine la primera y última línea
holroy
Y si desea excluir todas las líneas intermedias, es decir, desea ver solo las líneas que están fuera de las dos coincidencias, entonces: sed -n -e '/pattern A/,/pattern D/d; p'Esto dice, "elimine del patrón A al patrón D e imprima todo lo demás". Lamentablemente, este partido es codicioso. Eso significa que si los patrones A y D aparecen más de una vez, vas a hacer coincidir desde el primer patrón A hasta el último patrón D. Me temo que Perl o Python son tus amigos si ese es el caso.
fbicknel
16

¿por qué no usar awk?

awk '/Word A/,/Word D/' filename
cesar
fuente
2
sed parece ser capaz de hacer esto de manera mucho más eficiente si hay una gran cantidad de archivos involucrados. awk puede ser más fácil de recordar, pero sed parece valer una nota adhesiva en mi cerebro.
JimNim
1
awk es superior si Word Dcae en la misma línea que Word A, y posiblemente en otra parte, por ejemplo, Word A Word D\nWord Dcon sed mostrará dos líneas donde como awk mostrará una. Además, todavía se pueden usar variables con awk, por ejemplo, por awk -v _word="Word A" '$0 ~ _word,/Word D/' "/some/file"lo que puede ser más eficiente, pero cuando se trata de búsquedas de dos cadenas que pueden o no caer en la misma línea, awk definitivamente será más confiable.
S0AndS0
parece que awk maneja mejor el caso en que el archivo contiene secuencias de Ay Bsolo desea capturar lo que hay entre cada secuencia. Parece que sed no sigue esta semántica en mi caso al menos.
Matan
9
perl -lne 'print if /Word A/ .. /Word D/' file

o

cat file | perl -lne 'print if /Word A/ .. /Word D/'
vinian
fuente
1
+1 para contrarrestar el voto negativo de conducción. Todavía lo usaría sedpara esto, a menos que necesite el poder de las expresiones regulares de Perl para seleccionar las líneas delimitadoras.
tripleee
Las personas que escribieron sed en los años 70 deben estar agradecidos :-)
Matan