grep une ligne avant le match plus le match

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

dans la ligne ci-dessus, ce que je veux, c'est une ligne grep/ sed/ awk(n'importe quelle méthode est très bien) qui a un &signe plus une ligne au-dessus d'eux. ainsi, par exemple, la sortie souhaitée ressemblera à:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

voici ce que j'ai essayé sans chance.

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

Réponses:

16

Tu peux faire:

grep -B 1 '&$' your_file

Cela recherchera les lignes se terminant par &, supprimer $pour faire correspondre les lignes avec &n'importe où en eux.

Le -Bcommutateur indique grepde sortir les lignes "contextuelles" qui précèdent les lignes qui correspondent. Dans ce cas, puisque vous voulez une ligne de contexte, vous en avez besoin -B 1.

Ce commutateur est disponible dans GNU grepmais n'est pas dans la norme POSIX, cependant.

Voici une sedsolution simple qui devrait vous aider si vous n'avez pas GNU grep:

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

Comment ça fonctionne

  • Le -ncommutateur supprime l'action "d'impression" par défaut desed
  • /&/!Nsignifie: si la ligne actuelle ne contient pas &, ajoutez la ligne suivante à l'espace de motif.
  • /&/psignifie: faire correspondre &et imprimer l'espace du motif.
Joseph R.
la source
2
@RanaKhan Bienvenue sur Stack Exchange :) Je suis heureux d'avoir pu vous aider. N'oubliez pas de marquer cette réponse comme acceptée (utilisez la coche sous les boutons de vote à côté de la réponse) si cela a aidé à résoudre votre problème afin que les autres utilisateurs du site sachent que ce problème est résolu.
Joseph R.
+1 pour la variante lorsqu'elle GNU/grepn'est pas disponible, merci!
ckujau
3

Voici comment émuler grep -B1avec sed:

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

C'est très similaire à celui ici . Tout comme l'autre, il lit dans la Nligne ext mais cette fois, il Pimprime jusqu'à la première ligne \nélectronique si l'espace de motif correspond , puis, tout comme l'autre, se Dtermine jusqu'à la première ligne \nélectronique et redémarre le cycle. Donc, avec votre exemple d'entrée:

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

les sorties:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

Encore une fois, pour voir comment cela fonctionne, ajoutez lavant et après le Npour regarder l'espace modèle:

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

par exemple avec un exemple de fichier:

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

ce sont les commandes qui seds'exécutent et la sortie correspondante:

sortie cmd 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
la source