GNU/Linux >> Linux Esercitazione >  >> Linux

Stampa la riga precedente dopo una corrispondenza di pattern utilizzando Sed?

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 modello

    p :stampa la riga precedente

    d :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.


Linux
  1. Utilizzo di Sed per cercare e sostituire una linea tra intervalli di pattern

  2. Corrispondenza di pattern multilinea utilizzando Sed, Awk o Grep?

  3. Trova il numero di riga che contiene il modello utilizzando il delimitatore Regex personalizzato?

  4. Schema di sostituzione dopo l'ennesima corrispondenza trovata su ogni riga??

  5. Restituire solo la parte di una linea dopo uno schema corrispondente?

Come eseguire la ricerca del modello nei file utilizzando Grep

Come rimuovere le righe da un file usando il comando Sed

sed - inserisce riga dopo X righe dopo la corrispondenza

Bash - Come stampare stringhe multilinea (con '\n') usando printf

Come inserisco il testo nella prima riga di un file usando sed?

Utilizzo di sed per sostituire uno schema specifico