GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Vorherige Zeile nach einer Musterübereinstimmung mit Sed drucken?

Ich möchte die vorherige Zeile jedes Mal drucken, wenn eine Übereinstimmung gefunden wurde. Ich kenne grep -A und -B Optionen. Aber mein Solaris 5.10-Rechner unterstützt diese Optionen nicht.

Ich möchte eine Lösung, die nur sed verwendet .

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

Das Muster, das ich zuzuordnen versuche, war age is : 10 .

Meine Umgebung, Solaris 5.10.

Akzeptierte Antwort:

$ sed -n '/age is : 10/{x;p;d;}; x' Foo.txt 
Name is : sara
Name is : Ron

Das obige wurde auf GNU sed getestet. Wenn sed von Solaris das Verketten von Befehlen mit Semikolons nicht unterstützt, versuchen Sie Folgendes:

$ sed -n -e '/age is : 10/{x;p;d;}' -e x Foo.txt 
Name is : sara
Name is : Ron

Wie es funktioniert

sed hat einen Haltebereich und einen Musterbereich. Zeilenumbrüche werden in den Musterraum eingelesen. Die Idee dieses Skripts ist, dass die vorherige Zeile im Haltebereich gespeichert wird.

  • /age is : 10/{x;p;d;}

    Wenn die aktuelle Zeile age is : 10 enthält , dann tun:

    x :Tauschen Sie das Muster aus und halten Sie die Leerstelle, sodass sich die vorherige Zeile im Musterbereich befindet

    p :gibt die vorherige Zeile aus

    d :Lösche den Musterbereich und beginne mit der Verarbeitung der nächsten Zeile

  • x

    Dies wird nur auf Zeilen ausgeführt, die age is : 10 nicht enthalten . In diesem Fall speichert es die aktuelle Zeile im Haltebereich.

Das Gegenteil tun

Angenommen, wir möchten die Namen von Personen ausgeben, deren Alter nicht ist 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

Das obige fügt am Anfang einen Befehl hinzu, /age is : 10/{x;d} , alle Alters-10 Leute zu ignorieren. Der folgende Befehl, /age is :/{x;p;d;} , akzeptiert jetzt alle verbleibenden Alter.


Linux
  1. Verwenden von Sed zum Suchen und Ersetzen einer Linie zwischen Musterbereichen

  2. Mehrzeiliger Musterabgleich mit Sed, Awk oder Grep?

  3. Finden Sie die Zeilennummer, die das Muster enthält, mit benutzerdefiniertem Regex-Trennzeichen?

  4. Muster ersetzen, nachdem N-te Übereinstimmung in jeder Zeile gefunden wurde??

  5. Nur den Teil einer Linie nach einem übereinstimmenden Muster zurückgeben?

So führen Sie eine Mustersuche in Dateien mit Grep durch

So entfernen Sie Zeilen aus einer Datei mit dem Sed-Befehl

Vorherige Zeile drucken, wenn die Bedingung erfüllt ist

sed - Zeile nach X Zeilen nach Übereinstimmung einfügen

Bash - So drucken Sie mehrzeilige Zeichenfolgen (mit '\n') mit printf

Wie füge ich mit sed Text in die erste Zeile einer Datei ein?