grep una línea antes del partido más el partido

8
zzzzzzzzz
aaaaaaaaa
bbbbbbbbb &
ccccccccc &
ddddddddd
hhhhhhhhh
eeeeeeeee
fffffffff &
ggggggggg &

en la línea anterior, lo que quiero es grep/ sed/ awk(cualquier método está bien) una línea que tenga un &signo más una línea encima. así, por ejemplo, el resultado deseado se verá así:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

Lo siguiente es lo que he intentado sin suerte.

egrep "&" | -b 1 file.txt
Rana Khan
fuente

Respuestas:

16

Tu puedes hacer:

grep -B 1 '&$' your_file

Esto buscará líneas que terminen en &, elimínelas $para que coincidan con &cualquier parte de ellas.

El -Bconmutador le indica grepa la salida las líneas de "contexto" que vienen antes de las líneas que coinciden. En este caso, dado que desea una línea de contexto, necesita -B 1.

Sin grepembargo, este conmutador está disponible en GNU pero no está en el estándar POSIX.

Aquí hay una sedsolución simple que debería ayudar en caso de que no tenga GNU grep:

sed -n '/&/!N;/&/p' your_file

Cómo funciona

  • El -ninterruptor suprime la acción predeterminada "imprimir" desed
  • /&/!Nsignifica: si la línea actual no contiene &, agregue la siguiente línea al espacio del patrón.
  • /&/psignifica: emparejar &e imprimir el espacio del patrón.
Joseph R.
fuente
2
@RanaKhan Bienvenido a Stack Exchange :) Me alegro de poder ayudar. No olvide marcar esta respuesta como aceptada (use la marca de verificación debajo de los botones de voto al lado de la respuesta) si ayudó a resolver su problema para que otras personas que naveguen por el sitio sepan que este problema está resuelto.
Joseph R.
+1 para la variante cuando GNU/grepno está disponible, ¡gracias!
ckujau
3

Aquí se explica cómo emular grep -B1con sed:

sed '$!N;/pattern/P;D' infile

Es muy similar al de aquí . Al igual que el otro, se lee en la Nlínea de extensión, pero esta vez, se Palinea hasta la primera línea de \nflujo si el espacio del patrón coincide , y luego, al igual que el otro, Delige la primera línea de \nflujo y reinicia el ciclo. Entonces, con su entrada de muestra:

sed '$!N;/&/P;D' infile

salidas:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

Nuevamente, para ver cómo funciona, agregue lantes y después de Npara ver el espacio del patrón ::

sed 'l;$!N;l;/&/P;D' infile

por ejemplo, con un archivo de muestra:

zzzz &
aaaa
bbbb
cccc &
dddd &
hhhh
eeee
ffff &
gggg &

Estos son los comandos que se sedejecutan y la salida correspondiente:

cmd salida cmd
l       zzzz &$               N # read in the next line
l       zzzz &\naaaa$         # pattern space matches so print up to \n
P       zzzz &                D # delete up to \n 
l       aaaa$                 N # read in the next line
l       aaaa\nbbbb$           D # delete up to \n (no match so no P)
l       bbbb$                 N # read in the next line
l       bbbb\ncccc &$         # pattern space matches so print up to \n
P       bbbb                  D # delete up to \n
l       cccc &$               N # read in the next line
l       cccc &\ndddd &$       # pattern space matches so print up to \n
P       cccc &                D # delete up to \n
l       dddd &$               N # read in the next line
l       dddd &\nhhhh$         # pattern space matches so print up to \n
P       dddd &                D # delete up to \n
l       hhhh$                 N # read in the next line
l       hhhh\neeee$           D # delete up to \n (no match so no P)
l       eeee$                 N # read in the next line
l       eeee\nffff &$         # pattern space matches so print up to \n
P       eeee                  D # delete up to \n
l       ffff &$               N # read in the next line
l       ffff &\ngggg &$       # pattern space matches so print up to \n
P       ffff &                D # delete up to \n
l       gggg &$               # last line so no N 
l       gggg &$               # pattern space matches so print up to \n
P       gggg &                D # delete up to \n
don_crissti
fuente