Übersicht |
Der Stream Editor ist kein herkömmlicher Editor wie Vi oder Emacs. Der Sed arbeitet nicht interaktiv; er wird mittels Kommandozeilenoptionen oder durch ein Skript gesteuert. Der Stream Editor modifiziert niemals das Original, sondern schreibt das Ergebnis auf die Standard-Ausgabe. Die aktuell betrachtete Zeile lädt der Sed in einen temporären Puffer - nachfolgend als Arbeitspuffer bezeichnet.
Der Aufruf des Stream Editors auf der Kommandozeile besitzt immer folgendes Format:
sed 'Kommando' Dateiname |
Die Kommandos des Sed |
Die Aktionen von Sed werden durch Kommandos gesteuert. Diese Kommandos können Zeilenangaben oder -bereiche enthalten, dann betrachtet der Editor nur die Zeilen der zu bearbeitenden Datei. Fehlt eine solche Angabe, bearbeitet Sed die gesamte Datei.
Bevor wir das Verhalten anhand von Beispielen kennen lernen, seien alle Kommandos aufgeführt:
a
c
d
g
G
h
H
i
l
n
p
q
r
!
Substitutionskommandos des Sed |
Im Zusammenhang mit Substitutionen werden die Kommandos häufig als Flags bezeichnet. Beachten Sie, dass die Wirkung mancher Kommandos (»g«) aus dem Kontext entschieden wird.
g
p
s
w
x
y
Reguläre Ausdrücke des Sed |
Von den Regulären Ausdrücken versteht der Stream Editor Folgende:
^
$
.
*
[...]
[^...]
\(...\)
&
\<
\>
x\{m\}
x\{m,\}
x\{m,n\}
Adressierung und Beispieltext |
Die Handhabung des Stream Editors erlernen Sie vermutlich nur durch Beispiele. Es liegt also nahe, dem Leser mittels des Beispieltextes gleichzeitig neues Wissen einzuimpfen. Die folgende Abhandlung diskutiert die Adressierungsmöglichkeiten des Sed (das Schema lässt sich u.a. auch im Vi anwenden):
|
Um die spätere Arbeit des Editors besser verfolgen zu können, nummerieren wir noch die Datei:
|
Ausgabe - Das p-Kommando |
Zunächst wenden wir das Kommando p auf die ersten 3 Zeilen der Datei an:
|
Offensichtlich zeigt der Stream Editor etwas mehr an, als uns lieb ist; er gibt einfach die gesamte Datei aus und wiederholt nur die Zeilen, die durch das Kommando »1,3p« bearbeitet wurden. Um solche »überflüssigen« Ausgaben zu unterbinden, muss die Option »-n« verwendet werden:
|
Bei der Adressierung mittels regulärer Ausdrücke müssen diese in Schrägstriche (Slashes) eingeschlossen sein:
|
Löschen - Das d-Kommando |
Der nachfolgende Aufruf löscht alle Zeilen ab der (einschließlich) 4. bis zum Dateiende:
|
Das Entfernen aller Zeilen, die mit einem Leerzeichen beginnen, erledigt dieser Aufruf:
|
Ersetzen - Das s-Kommando |
Das dem s-Kommando folgende Zeichen wird als Trennzeichen angesehen. Anschließend folgt das Suchmuster und, getrennt durch das Trennzeichen, das Ersatzmuster, welches wiederum mittels des Trennzeichens abgeschlossen wird. Prinzipiell kann jedes druckbare Zeichen als Trennzeichen Verwendung finden, es selbst darf allerdings kein Bestandteil eines Musters sein! Eine Substitution sieht demnach wie folgt aus:
sed 's/altes Muster/neues Muster/' datei sed 's?altes Muster?neues Muster?' datei |
Im Beispiel ersetzen wir »RegEx« durch »Regulärer Ausdruck«:
|
Wer genau hinschaute, wird im letzten Beispiel eine fehlende Ersetzung von »RegEx« bemerkt haben (Zeile 14). Der Editor bearbeitet in jeder Zeile nur das erste Vorkommen. Um alle Muster zu ersetzen, ist das Kommando »g« nachzustellen:
|
Da wir nur an den modifizierten Zeilen interessiert sind, haben wir das Sed mitgeteilt (Option -n). Allerdings würde nun das Substitutionskommando die gesamte Ausgabe unterdrücken, hätten wir dem nicht mit dem p-Kommando entgegen gewirkt.
Ein (zugegeben... etwas konstruiertes) Beispiel soll das Speichern von Mustern und den späteren Zugriff darauf demonstrieren. Es soll die Nummerierung der Zeilen von Einer- auf Zehnerschritte erhöht werden:
|
Das Beispiel profitiert von dem Wissen, dass die Zeilenummer am Beginn der Zeile zu finden ist. Das Muster, dem unser Interesse gilt, sind alle Ziffern zu Beginn der Zeile, wobei führende Leerzeichen durchaus möglich sind. Genau jenes Muster merken wir uns für den späteren Gebrauch vor, indem wir es in »\(...\)« einschlie&szlIg;en. Der Zugriff auf dieses erste gespeicherte Muster im Ersatzmuster erfolgt durch »\1«.
Bis zu 9 Muster lassen sich pro Zeile speichern, die entsprechend ihrer Reihenfolge mittels \1, \2,... \9 referenziert werden.
Mehrere Kommandos - Die e-Option |
Das Problem mit Kommandos wie »s« ist, dass sie keine Adressierung zulassen. Sicher gibt es Situationen, wo nur ein Teil einer Datei zu bearbeiten ist. Hier hilft das e-Kommando, mit dem sich beliebig viele Kommandos kombinieren lassen:
|
Zuerst werden alle Zeilen ab der 3. Zeile entfernt und anschließend die Leerzeichen durch Punkte ersetzt. Aber Vorsicht... mitunter beeinflusst die Reihenfolge der Kommandos das Ergebnis!
Eine alternative Angabe ist die Gruppierung mehrerer Kommandos. Hierzu werden diese in geschweifte Klammern gesetzt und ein Semikolon nach jedem Kommando eingefügt
|
Einfügen - Das i- und das a-Kommando |
Die Syntax zum Einfügen ist wohl etwas gewöhnungsbedürftig. Der einzufügende Text muss auf einer neuen Zeile stehen, wobei jede Zeile bis auf die letzte durch einen Backslash abzuschließen ist. Das Kommando »i« (insert) fügt den Text vor der betreffenden Zeile ein, »a« (append) schreibt den neuen Text nach der Zeile.
|
Einfügen aus einer Datei - Das r-Kommando |
Wohl in seltenen Fällen wird ein Text nur in eine einzige Datei eingefügt werden (sonst wäre der Griff zu einem herkömmlichen Editors der effizientere Weg). Eine gangbare Methode ist, den einzusetzenden Text in einer separaten Datei zu erfassen und Sed jene unterzuschieben.
|
Dieser Text lässt sich mittels des r-Kommandos einfach an beliebiger Stelle einordnen:
|
Schreiben in eine Datei - Das w-Kommando |
Das Ergebnis des Stream Editors lässt sich in einer Datei speichern:
|
Die nächste Zeile - Das n-Kommando |
Soll erst die dem Suchmuster folgende Zeile manipuliert werden, ist das n-Kommando der beste Kandidat::
|
Die Kommandozeile ist schwer verdaulich... aber der Reihe nach:
»-n« als Kommandozeilenoption besagt, dass de Ausgabe einzig die bearbeiteten Zeilen betreffen soll. Da jedoch das Flag »s« sämtliche Ausgaben »verschluckt«, muss »p« am Ende bemüht werden.
»8,$« adressiert die Zeilen 8 bis zum Ende der Datei. Die erste Zeile, die also gefunden wurde, ist die 8. »-n« als Substitutionskommando bewirkt nun, dass die nächste Zeile in die Mangel genommen wird - Zeile 9.
Diese 9. Zeile wird nun substituiert. ».\{1,\}« meint »mindestens ein (\{1,\}) beliebiges (.) Zeichen. Da jede Zeile im Beispiel zumindest die Zeilenummer umfasst und das komplette Muster via »\(...\)« gespeichert wird, erscheint die gesamte Zeile mit vorangestelltem Stern (*\1) in der Ausgabe...
Sed fährt mit der folgenden Zeile (10) fort, die (wegen Flag »n«) übersprungen wird...
Zeichentausch - Das y-Kommando |
Einzelne Zeichen lassen sich durch andere einzelne Zeichen ersetzen. Das Zeichen an Position x der Liste zu ersetzender Zeichen wird in das Zeichen an Position x der Liste der neuen Zeichen transformatiert. Damit ist klar, dass beide Zeichenlisten dieselbe Länge besitzen müssen:
|
Sed beenden - Das q-Kommando |
Manchmal ist es sinnvoll, den Stream Editor vorzeitig zu beenden:
|
Zeilentausch - Die Kommandos h, g, G und x |
Die soeben bearbeitete Zeile hält der Sed in einem Zwischenspeicher und bearbeitet diese in diesem »Pattern Space«. Hat der Editor seine Arbeit beendet, gibt er die Zeile aus und lädt die folgende Zeile der Eingabedatei in den Zwischenspeicher.
Mit dem Kommando »h« kann der aktuelle Zwischenspeicher in einen Puffer gesichert werden (»holding buffer«). Das Kommando »G« fügt den Inhalt dieses Sicherungspuffers hinter der aktuell bearbeiteten Zeile ein; »g« ersetzt die aktuelle Zeile durch den Inhalt des Sicherungspuffers. Den Inhalt der beiden Puffer vertauscht das Kommando »x«.
|
Erklärung: Das erste Kommando »-e '/sed/{h;d;}'« in beiden Aufrufen teilt dem Editor mit, die Zeile, die Sed enthält, zuerst in den Zwischenspeicher zu sichern und nachfolgend zu löschen. Das zweite Kommando vollzieht das Einfügen des Inhalts des Puffers. »-e '4G'« fügt nach der 4.Zeile ein (Achtung: die gelöschte Zeile wird mitgezählt!); »-e '4Gg'« ersetzt die 4.Zeile. Das letzte Kommando »-e '4q'« beendet die Arbeit des Editors nach der 4. Zeile.
|
Erklärung: Enthält eine Zeile das Muster »Aufruf«, wird sie im Zwischenpuffer abgelegt. Steht in einer Zeile »Angabe«, so wird diese Zeile mit dem Inhalt des Zwischenpuffers vertauscht. Der Inhalt des Zwischenpuffers wird hinter der letzten Zeile eingefügt.
Sed-Skripte |
Kompliziertere und häufig benötigte Sed-Aufrufe schreibt man besser in eine Datei. Ein Aufruf des Editors sieht dann wie folgt aus:
sed -f <Skript_Datei> <zu_bearbeitende_Datei> |
Beim Schreiben eines Skripts gelten folgende Regeln:
Der Stream Editor wird das gesamte Skript auf jede Zeile der Eingabedatei anwenden.
Als Beispiel dient ein kleines Skript, dass alle deutschen Umlaute in der Eingabedatei durch den entsprechenden Unicode (für html) ersetzt.
user@sonne> cat umlaut # Ersetzen der äüö... durch Unicode s/ä/\ä/g s/ü/\ü/g s/ö/\ö/g s/Ä/\Ä/g s/Ü/\Ü/g s/Ö/\Ö/g s/ß/\ß/g |
Das Anwendungsbeispiel demonstriert die Möglichkeit der Kopplung von Kommandozeilenbefehlen und einem Skript:
|