Fischertechnik
AVR
Raspberry Pi
Elektronik
Netzwerk
Sonstiges


















Impressum

sed der "stream editor"

Viele Daten, Konfigurationsdateien oder auch Mess- oder Zugriffsprotokolle enthalten die Nutzinformation für bestimmte Auswertungen nicht in der optimalen Form. Mit sed steht ein sehr leistungsfähiges Werkzeug zur Verfügung, um die Daten geeignet aufzubereiten.

Grundlagen

Adressierung

Viele Befehle erlauben das Voranstellen der Zeilen, auf die der Befehl angewendet werden soll. 1,$p führt von der ersten bis zur letzten Zeile ($) den Befehl p aus. 1p;$p führt den Befehl für die erste und die letzte Zeile aus. Statt der Zeilennummer können auch Suchmuster angegeben werden. /Start/,$p führt den Befehl p ab der ersten Zeile, die Start enthält bis zur letzten Zeile aus.
Komplexe Bedingungen lassen sich mit Sprüngen im Skript lesbar realisieren.

1b first
2,$p
d
:first
${s/^/Nur eine einzige Zeile: /;p;d}
p

In diesem Beispiel wird eine Sonderbehandlung für die erste Zeile ab dem Label first durchgeführt. Hier wird eine Regel für die letzte Zeile umgesetzt, die dann im Gesamtkontext nur ausgeführt wird, wenn die erste auch die letzte Zeile ist.
Mehrzeilige Opererationen (s.u.) erfordern oft eine Sonderbehandlung der ersten, oder letzten Zeile. Dieses ist mit den Sprüngen leicht möglich.

Puffer

sed verfügt über zwei Puffer. Der "pattern space" ist derjenige, mit dem die meisten Operationen durchgeführt werden. Zusätzlich gibt des den "hold space", der als Zwischenspeicher genutzt werden kann. Die Puffer können vertauscht, ersetzt und verkettet werden und bieten somit komplexe Möglichkeiten. Ein entstehendes Risiko ist, dass zwischengespeicherte Informationen beim Erreichen der letzten Zeile nicht mehr ausgegeben werden; hier ist besondere Vorsicht bei der Erstellung des Skripts erforderlich.
xAustausch der Puffer
hErsetze hold space durch den Inhalt des pattern space
HHänge pattern space an hold space an. Die Zeilenenden bleiben dabei erhalten und müssen bei Bedarf entfernt werden.
gErsetze pattern space durch den Inhalt des hold space
GHänge hold space an pattern space an. Die Zeilenenden bleiben dabei erhalten und müssen bei Bedarf entfernt werden.

Zeilen in umgekehrter Reihenfolge ausgeben

Mit diesem kurzen Skript 1!G;h;$!d werden die Eingangszeilen in umgekehrter Folge ausgegeben. Erklärung: Alle Zeilen werden im hold space gesammelt; mit G wird an jede neue Zeile der bestehende hold space angehängt. Für die erste Zeile ergibt das keinen Sinn; für diese wird mit h der hold space durch den pattern space ersetzt. Dieses erfolgt für die anderen Zeilen nach dem Verketten ebenfalls, so dass sowohl im hold space, als auch im pattern space immer alle Zeilen enthalten sind. Jetzt wird mit d die nächste Zeilenverarbeitung angestoßen. Einzige Ausnahme ist die letzte Zeile. Da kein expliziter Befehl für diese Zeile vorhanden ist, wird der pattern space ausgegeben. Dieser enthät die Eingangsdaten in umgekehrter Reihenfolge.

Verbinden mehrere Zeilen

Liegen zusammengehörige Informationen in mehreren aufeinanderfolgenden Zeile vor, ist es häufig sinnvoll diese in eine Zeile zu verbinden, Folgeoperationen zeilenbasiert durchzuführen und ggf. anschließend wieder die alte mehrzeilige Form wiederherzustellen. Für den hier skizzierten Weg mit sed ist es erforderlich die jeweils zusammenhängenden Daten formal beschreiben, bzw. erkennen zu können.

Leerzeilen als Trennung


Eingangsdaten:

----- snip -----
1. Zeile
2. Zeile

4. Zeile
5. Zeile
----- snip -----
Skript:
sed -n '/^[ \t]*$/{x;s/\n/|/g;s/^|//;P;D};${H;x;s/\n/|/g;s/^|//;P};{H}'

oder als Skript-Datei:
/^[ \t]*$/{x;s/\n/|/g;s/^|//;P;D}
${H;x;s/\n/|/g;s/^|//;P}
{H}

Ausgangsdaten:

----- snip -----
1. Zeile|2. Zeile
4. Zeile|5. Zeile
----- snip -----


Erklärung: Zu Beginn wird die Erkennung eines neuen Blocks bearbeitet. Alle Zeilen, die nur aus white space bestehen /^[ \t]*$/ als Kriterium. Dieses kann dann leicht an andere Gegebenheiten angepasst werden. Jetzt wird der hold space geholt (x), die Zeilenumbrüche gewandelt (s/\n/|/g), der Zeilenanfang korrigiert (s/^|//), gedruckt P und der pattern space gelöscht (D).
Als Nächstes wird die letzte Zeile behandelt: pattern space an den hold space anhängen H, die Zeilenumbrüche gewandelt (s/\n/|/g), der Zeilenanfang korrigiert (s/^|//) und gedruckt P.
Zum Abschluss erfolgt die Abarbeitung der restlichen Zeilen; hier nur die Verkettung der beiden Puffer (H); die Klammern könnten entfallen.

INI-Dateien


Eingangsdaten:

----- snip -----
[section 1]
a=a
b=b
[section 2]
c=c
d=d
[section 3]
[section 4]
----- snip -----
Skript als Skript-Datei:
${s/\([[].*[]]\)/\1/;t new;H;x;s/\n/|/g;s/^|//;P}
1{h;D}
/^[[].*[]]$/{x;s/\n/|/g;s/^|//;P;D}
{H}
d
:new 
{x;s/\n/|/g;s/^|//;P;x;P}

Ausgangsdaten:

----- snip -----
[section 1]|a=a|b=b
[section 2]|c=c|d=d
[section 3]
[section 4]
----- snip -----


Erklärung: Das Skript beginnt mit der Regel für die letzte Zeile. Da hier eine unterschiedliche Behandlung erforderlich ist, je nachdem, ob ein neuer Block beginnt oder nicht erfolgt ein Test auf einen neuen Block mit einem bedingten Sprung zum Label :new (s/\([[].*[]]\)/\1/;t new;). Der pattern space bleibt dabei unverändert. Wenn es eine Folgezeile ist, erfolgt die bekannte Abarbeitung: An hold space anhängen, tauschen, Zeilenenden ersetzen und ausgeben. Wenn es ein neuer Block war, dann wird erst der hold space aufbereitet, ausgegeben und im Anschluss die aktuelle Zeile zurückgeholt und ausgegeben. Wenn die Eingabe nur aus einer einzigen Zeile besteht, dann wird durch die Ausgabe des hold space vor der Ausgabe der letzten Zeile in der Ausgabe eine Leerzeile erzeugt.