@Ed Morton: No estoy de acuerdo contigo aquí. Encontré sedmuy útil y simple (una vez que asimilas el concepto del patrón y mantienes los búferes) para encontrar una forma elegante de hacer grepping multilínea.
Por ejemplo, tomemos un archivo de texto que tiene nombres de host y algo de información sobre cada host, con mucha basura en el medio que no me importa.
Host: foo1
some junk, doesnt matter
some junk, doesnt matter
Info: about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Info: a second line about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Host: foo2
some junk, doesnt matter
Info: about foo2 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Para mí, un script awk para obtener las líneas con el nombre de host y la infolínea correspondiente tomaría un poco más de lo que puedo hacer con sed:
sed -n '/Host:/{h}; /Info/{x;p;x;p;}' myfile.txt
la salida se ve así:
Host: foo1
Info: about foo1 that I really care about!!
Host: foo1
Info: a second line about foo1 that I really care about!!
Host: foo2
Info: about foo2 that I really care about!!
(Tenga en cuenta que Host: foo1aparece dos veces en la salida).
Explicación:
-n desactiva la salida a menos que se imprima explícitamente
- primera coincidencia, busca y coloca la
Host:línea en el búfer de retención (h)
- segunda coincidencia, encuentra la siguiente línea Info:, pero primero intercambia (x) la línea actual en el búfer de patrón con el búfer de retención, e imprime (p) la
Host:línea, luego vuelve a intercambiar (x) e imprime (p) la línea Info :.
Sí, este es un ejemplo simplista, pero sospecho que este es un problema común que se solucionó rápidamente con un simple sed one-liner. Para tareas mucho más complejas, como aquellas en las que no puede confiar en una secuencia predecible y dada, awk puede ser más adecuado.
echo $'1\n2\n3\n4' | sed -n '1~2h;2~2{p;x;p}'