Voglio stampare la riga precedente, ogni volta che è stata trovata una corrispondenza. Conosco grep -A
e -B
opzioni. Ma la mia macchina Solaris 5.10 non supporta queste opzioni.
Voglio una soluzione usando solo 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
Il modello che sto cercando di abbinare era age is : 10
.
Il mio ambiente, Solaris 5.10.
Risposta accettata:
$ sed -n '/age is : 10/{x;p;d;}; x' Foo.txt
Name is : sara
Name is : Ron
Quanto sopra è stato testato su GNU sed. Se sed di Solaris non supporta il concatenamento dei comandi insieme ai punti e virgola, prova:
$ sed -n -e '/age is : 10/{x;p;d;}' -e x Foo.txt
Name is : sara
Name is : Ron
Come funziona
sed ha uno spazio di attesa e uno spazio di pattern. Le nuove righe vengono lette nello spazio del modello. L'idea di questo script è che la riga precedente venga salvata nello spazio di attesa.
-
/age is : 10/{x;p;d;}
Se la riga corrente contiene
age is : 10
, quindi fai:x
:scambia il modello e tieni lo spazio in modo che la riga precedente sia nello spazio del modellop
:stampa la riga precedented
:elimina lo spazio del pattern e inizia l'elaborazione della riga successiva -
x
Questo viene eseguito solo su righe che non contengono
age is : 10
. In questo caso, salva la riga corrente nello spazio di attesa.
Fare il contrario
Supponiamo di voler stampare i nomi per le persone la cui età non 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
Quanto sopra aggiunge un comando all'inizio, /age is : 10/{x;d}
, per ignorare qualsiasi persona di età inferiore ai 10 anni. Il comando che segue, /age is :/{x;p;d;}
, ora accetta tutte le età rimanenti.