Je veux imprimer la ligne précédente, chaque fois qu'une correspondance a été trouvée. Je connais grep -A
et -B
options. Mais ma machine Solaris 5.10 ne prend pas en charge ces options.
Je veux une solution en utilisant uniquement sed
.
Foo.txt
:
Name is : sara
age is : 10
Name is : john
age is : 20
Name is : Ron
age is : 10
Name is : peggy
age is : 30
Out.txt
:
Name is : sara
Name is : Ron
Le modèle que j'essaie de faire correspondre était age is : 10
.
Mon environnement, Solaris 5.10.
Réponse acceptée :
$ sed -n '/age is : 10/{x;p;d;}; x' Foo.txt
Name is : sara
Name is : Ron
Ce qui précède a été testé sur GNU sed. Si le sed de Solaris ne prend pas en charge les commandes de chaînage avec des points-virgules, essayez :
$ sed -n -e '/age is : 10/{x;p;d;}' -e x Foo.txt
Name is : sara
Name is : Ron
Comment ça marche
sed a un espace de maintien et un espace de modèle. Les retours à la ligne sont lus dans l'espace du motif. L'idée de ce script est que la ligne précédente est enregistrée dans l'espace de maintien.
-
/age is : 10/{x;p;d;}
Si la ligne courante contient
age is : 10
, puis faites :x
:échangez le motif et maintenez l'espace pour que la ligne précédente soit dans l'espace du motifp
:imprime la ligne précédented
:supprimez l'espace du motif et commencez à traiter la ligne suivante -
x
Ceci est exécuté uniquement sur les lignes qui ne contiennent pas
age is : 10
. Dans ce cas, il enregistre la ligne courante dans l'espace de maintien.
Faire le contraire
Supposons que nous voulions imprimer les noms des personnes dont l'âge n'est pas 10 :
$ sed -n -e '/age is : 10/{x;d}' -e '/age is :/{x;p;d;}' -e x Foo.txt
Name is : john
Name is : peggy
Ce qui précède ajoute une commande au début, /age is : 10/{x;d}
, pour ignorer toute personne âgée de moins de 10 ans. La commande qui suit, /age is :/{x;p;d;}
, accepte désormais tous les âges restants.