Mit dem Linux SED-Befehl Daten schneller arbeiten
Viele Nutzer von Linux und seinen zahlreichen Distributionen arbeiten gelegentlich oder regelmäßig auf der Ebene der Kommandozeile. Im Terminal lassen sich einige Aufgaben schneller oder besser erledigen als in der grafischen Oberfläche. Dafür muss man allerdings die verschiedenen Befehle und ihre Funktionsweisen kennen. Ein solches Kommando in Linux ist ‚sed‘.
Zwar ist der Stream Editor (sed) ein Texteditor, aber nicht so, wie man sich eine solche Software landläufig vorstellt. In Linux ist SED ein Befehl, mit dem man Datenströme auslesen und anpassen kann. Man setzt das Werkzeug deshalb vor allem in der Shell-Programmierung ein. Wie funktioniert das?
Wozu setzt man in Linux SED ein?
Der Befehl ‚sed‘ gehört zur Grundausstattung von jeder Linux-Installation, da er zu den GNU Core Utilities (coreutils) gehört. Das Werkzeug wird als nichtinteraktiver Texteditor bezeichnet. Dies bedeutet, dass man eine Änderung nicht direkt an der Datei vornimmt, die bearbeitet wird. Stattdessen erzeugt man zunächst eine temporäre Datei, deren Inhalt anschließend an die Ausgangsdatei übergeben wird. Dabei geht Linux SED zeilenweise vor. Jede Zeile einer Datei wird einzeln eingelesen, bearbeitet und dann wieder ausgegeben. Die wichtigste Funktion von SED ist es, bestimmte Zeichenketten in der Datei zu suchen und dann durch andere Zeichen zu ersetzen.
Auf diese Weise können Sie eine komplette Datei – quasi automatisiert – mit nur einem Befehl grundlegend verändern. Wenn man solche Befehle in ein Shell-Skript integriert, kann man sich immer wiederholende Aufgaben stark vereinfachen. Auf diese Weise lassen sich beispielsweise Datenbanken oder ein umfangreicher Quellcode pflegen. Statt jeden Eintrag per Hand anzupassen, kann man mit SED die komplette Datei in einem Rutsch durchgehen.
Syntax und Funktion des SED-Befehls
Der SED-Befehl arbeitet mit Kommandos und wird auf Dateien angewendet. Sowohl der Befehl an sich als auch die Kommandos können noch durch Optionen erweitert werden.
sed [Option(en)] 'Kommando(s)' [Datei(en)]
Kommandos können Sie entweder direkt in den Befehl eintragen oder aus einer Datei auslesen. In letzterem Fall geben Sie dann statt dem Kommando den Pfad der Datei ein.
Optionen
Wie man es von Linux-Befehlen gewohnt ist, hat man auch bei SED die Möglichkeit, Parameter zu setzen. Diese sind beim SED-Befehl besonders wichtig, da erst durch sie klar wird, wie das darauffolgende Kommando interpretiert werden soll. Folgende Optionen kommen in Frage:
Option | Erklärung |
-e | Gibt an, dass ein oder mehrere SED-Skripte verwendet werden. |
-f | Gibt an, dass das Skript aus einer Datei gezogen wird. |
-n | Ergebnisse werden nicht ausgegeben. |
-i | Erzeugt eine temporärere Datei, die anschließend die Ausgangsdatei ersetzt. |
-u | Es wird kein Datenpuffer eingesetzt. |
-s | Mehrere Dateien werden separat behandelt statt als einem langen Datenstrom. |
-r | Der Befehl akzeptiert erweiterte reguläre Ausdrücke. |
Die Optionen -e und -f sind am wichtigsten. Sie geben an, ob das Kommando direkt im Befehl steht (dann handelt es sich um ein SED-Skript) oder ob der Befehl sich an eine zusätzliche Datei wenden muss. Auf die -e-Option können Sie oftmals verzichten, da es sich um den Standardfall handelt. Sobald man allerdings mehr als ein Kommando gleichzeitig in den Befehl einbaut, muss die Option zwingend aktiviert werden.
Wenn Sie die Option -e einsetzen, muss der Parameter direkt vor das erste Kommando geschrieben werden. Verwenden Sie noch weitere Optionen, schreiben Sie diese also davor. Bauen Sie weitere Kommandos in den Befehl ein, setzen Sie auch hier jeweils die Option voran.
Sehr wichtig – und vermutlich bei Ihrer Arbeit unverzichtbar – ist die Option -n. Ist der Parameter nicht gesetzt, wird jede einzelne Zeile der eingelesenen Textdatei im Terminal angezeigt, was gerade bei großen Datenbanken wenig sinnvoll ist. Wenn man die Option aktiviert, werden nur die Zeilen angezeigt, die vom Kommando auch betroffen sind.
Kommandos
Mit einem Kommando vermitteln Sie dem Befehl, was dieser mit der Ausgangsdatei und unter Berücksichtigung der angegebenen Optionen zu erledigen hat.
Kommando | Beschreibung |
a | append: Fügt den ausgesuchten Zeilen eine oder mehrere andere Zeilen hinzu. |
c | change: Ersetzt die ausgesuchten Zeilen mit neuem Inhalt. |
d | delete: Löscht die ausgesuchten Zeilen. |
g | get: Kopiert den Inhalt vom hold space in den pattern space. |
G | GetNewline: Fügt den Inhalt des hold space dem pattern space hinzu. |
h | hold: Kopiert den Inhalt vom pattern space in den hold space. |
H | HoldNewLine: Fügt den Inhalt des pattern space dem hold space hinzu. |
i | insert: Fügt eine oder mehrere Zeilen vor den ausgesuchten Zeilen ein. |
l | listing: Zeigt alle nicht druckbaren Zeichen an. |
n | next: Wechselt für die nächste Zeile zum folgenden Kommando im Befehl. |
p | print: Zeigt die ausgesuchten Zeilen an. |
q | quit: Beendet Linux SED. |
r | read: Liest ausgesuchte Zeilen aus einer Datei aus. |
s | substitute: Ersetzt eine festgelegte Zeichenfolge durch eine andere. |
x | xchange: Vertauscht pattern space und hold space miteinander. |
y | yank: Ersetzt ein festgelegtes Zeichen durch ein anderes. |
w | write: Schreibt Zeilen in eine Textdatei. |
! | Negation: Wendet das Kommando auf Zeilen an, die nicht auf die Eingabe zutreffen. |
Die beiden Speichertypen hold space und pattern space haben unterschiedliche Aufgaben: Der pattern space beschreibt einen kurzfristigen Arbeitsspeicher. Darin befinden sich die Daten, mit denen der Befehl gerade arbeitet. Der hold space ist langfristiger angelegt. Daten, die sich dort befinden, können auch dann noch abgerufen werden, wenn SED bereits mit etwas anderem beschäftigt ist.
Die Kommandos kann man zudem mit Optionen erweitern:
Option | Beschreibung |
= | Gibt die Zeilennummer der ausgesuchten Zeilen an. |
p | Gibt die geänderten Zeilen aus. |
g | Wendet das Kommando auf die komplette Datei an. |
Sie sollten Kommandos immer mit einfachen Anführungszeichen beginnen und enden lassen. Auf diese Weise verhindern Sie, dass die Eingabe reinterpretiert werden muss. Prinzipiell sind die Zeichen zwar nicht notwendig, aber so umgeht man viele Fehlerquellen.
Reguläre Ausdrücke
Für die Verwendung von SED ist es wichtig, reguläre Ausdrücke zu verstehen. Die Zeichen dienen dazu, dem Befehl mitzuteilen, wie dieser mit einer Folge von Zeichen umzugehen hat. Wichtig sind beispielsweise eckige und runde Klammern:
- [ABC]: Eine Zeichenklasse verwendet man dann, wenn man aus einer Gruppe von Buchstaben, Ziffern oder Symbolen eine Übereinstimmung sucht; also entweder A oder B oder C.
- (ABC): Eine Zeichengruppe beschreibt einen festen Begriff; also ABC in dieser Reihenfolge.
Wildcards ermöglichen es bei regulären Ausdrücken, auch nur nach Teilen von Begriffen zu suchen. Sie können zwei verschiedene Varianten verwenden:
- .: Der Punkt ersetzt genau ein Zeichen.
- *: Der Asterisk ersetzt beliebig viele Zeichen.
Zudem geben Ihnen reguläre Ausdrücke die Möglichkeit, die Häufigkeit von Zeichen(-Kombinationen) genauer zu bestimmen.
- ?: Das Fragezeichen gibt an, dass ein Begriff einmal oder gar nicht vorkommen darf.
- +: Das Pluszeichen legt fest, dass das Zeichen mehrmals, aber mindestens einmal vorkommt.
- {0,n}: Mit einer Zahl innerhalb von geschweiften Klammern legen Sie genau fest, wie oft die Zeichenkombination vorkommen darf. Wenn Sie zwei Werte eingeben (mit einem Komma getrennt), bestimmen Sie die minimalen und maximalen Wiederholungen.
Schließlich können Sie beim Umgang mit Linux und SED auch noch logische Zeichen einbauen, die Ihnen beispielsweise beim Verknüpfen oder Verschachteln von Suchanfragen helfen.
- |: Eine Pipe steht zwischen zwei Begriffen und symbolisiert eine Alternative der beiden.
- ^: Das Zirkumflex (direkt vor einen Begriff geschrieben) negiert diesen; diese Zeichenfolge darf demnach nicht vorkommen.
Mit diesen Zeichen modifizieren Sie also die Eingabe im SED-Befehl und können auf diese Weise komplexe Aufgaben erledigen.
Adressen
Die Eingaben werden bei Linux SED als Adressen bezeichnet. Eine Adresse ist also das Ziel des Befehls. Dieses können Sie auf unterschiedliche Weise angeben. In vielen Situationen werden Sie mit regulären Ausdrücken ausgeschmückte Suchanfragen eingeben. Es ist aber beispielsweise auch möglich, Zeilen der Textdatei direkt anzuwählen. Dementsprechend unterschiedlich notieren Sie die Adressen.
Im ersten Beispiel beziehen Sie sich auf konkrete Zeilen:
sed -n '10,50p' text.txt
Sie würden mit diesem Code die Zeilen 10 bis 50 im Terminal ausgeben.
Wissen Sie nicht genau, in welchen Zeilen die Informationen zu finden sind, mit denen Sie arbeiten wollen, können Sie nach der Adresse suchen lassen. Wichtig ist hierbei, dass Sie Ausdrücke immer mit Schrägstrichen beginnen und enden lassen. So trennen Sie den eigentlichen Suchbegriff von anderen Informationen wie etwa den Kommandos.
sed -n 'beispiel.[1-9]/p' text.txt
Dieser Code würde Ihnen alle Zeilen ausgeben, die als Beispiel oder als Beispiele bezeichnet sind und anschließend eine Ziffer haben.
SED an drei Beispielen erklärt
Der SED-Befehl kann in unterschiedlichsten Situationen schnelle Hilfe bringen. Besonders wenn Sie in umfangreiche Textdateien viele Änderungen auf einmal vornehmen müssen, spielt das Tool seine Stärken aus. In den folgenden drei Beispielen sehen Sie verschiedene Möglichkeiten, wie SED im Linux-Alltag eingesetzt werden kann.
Textdatei durchsuchen
Der einfachste Anwendungsfall ist das Suchen nach bestimmten Daten in einem Dokument. Interessant ist das beispielsweise in umfangreichen Datenbanken oder auch im Quellcode. So kann man schnell eine Stelle finden, die man entweder nur nachlesen oder auch abändern möchte.
Nehmen wir nun beispielhaft an, dass Sie in Ihrem ausladenden Weinkeller einen Chardonnay suchen. Zusätzlich möchten Sie auch die erste Zeile der Datenbank anzeigen lassen, in der die einzelnen Spalten erklärt werden. Folgender Befehl hilft Ihnen dabei, die Position der Flaschen zu finden:
sed -n -e '1p' -e '/Chardonnay/p' wein.txt
Sie verwenden hier zwei Kommandos nacheinander. Beide werden durch -e eingeleitet. Das Ergebnis sieht dann folgendermaßen aus:
Regal | Anbaugebiet | Rebsorte | Jahrgang |
1 | Pfalz | Chardonnay | 2001 |
2 | Mosel | Chardonnay | 1983 |
3 | Elsass | Chardonnay | 1981 |
Möchten Sie nun nur die Jahrgänge der 1980er Jahre anzeigen, geht auch das mit einer kleinen Abänderung des Codes.
sed -n -e '1p' -e '/Chardonnay * 198./p' wein.txt
Regal Anbaugebiet Rebsorte Jahrgang
2 Mosel Chardonnay 1983
3 Elsass Chardonnay 1981
Die Wildcard zwischen Rebsorte und Jahrgang ist prinzipiell in diesem Beispiel nicht wichtig. Falls die Datenbank jedoch fehlerhaft ist oder Sie nachträglich eine Spalte einfügen, bleibt die Angabe korrekt.
Informationen hinzufügen
Mit Linux und dem SED-Befehl können Sie auch Datenbanken erweitern. Um neue Einträge zu machen, müssen Sie die Datei also nicht mit einem kompletten Texteditor öffnen, ändern und speichern. Stattdessen nehmen Sie die Änderung mit nur einer Codezeile vor.
Für unser Beispiel nehmen wir jetzt an, dass Sie zwei neue Flaschen Wein für Ihre Sammlung erhalten haben. Diese möchten Sie verständlicherweise auch in der entsprechenden Datenbank eintragen. Sie können mit SED einfach ans Ende der Textdatei eine neue Zeile anhängen.
sed -i -e '$a2 Mosel Dornfelder 2010' -e '$a4 Elsass Grauburgunder 2011' wein.txt
Der reguläre Ausdruck $ sorgt dafür, dass SED zunächst in die letzte Zeile springt. Das Kommando a bewirkt das Hinzufügen einer neuen Zeile mit dem Inhalt, der schließlich folgt. Wir verwenden die Option -i, damit die Ausgangsdatei direkt abgeändert wird. Alternativ könnte man eine neue Datenbank erstellen:
sed -e '$a2 Mosel Dornfelder 2010' -e '$a4 Elsass Grauburgunder 2011' wein.txt > wein1.txt
Datenbanken pflegen
Möchte man in großen Datenbanken mit vielen Einträgen nachträglich den Aufbau ändern, ist das manuell kaum zu schaffen. Linux bietet mit SED aber eine schnelle Lösung. Bisher sind in Ihrer Datei die einzelnen Spalten durch ein Leerzeichen voneinander getrennt. Gehen wir nun in diesem Beispiel davon aus, dass Sie das Leerzeichen mit einem Bindestrich ersetzen möchten. Dafür verwenden wir das s-Kommando:
sed -i -e 's/[[:space:]]/-/g' wein.txt
Das g am Ende der Adresse sorgt dafür, dass der Befehl auf die komplette Datei angewendet wird.
Eine ähnliche Herausforderung stellt sich, wenn Sie zusätzliche Informationen innerhalb einer Zeile einfügen möchten. Nehmen wir nun beispielhaft an, Sie möchten zukünftig auch vermerken, ob Sie den Wein bereits probiert haben oder nicht. Bevor Sie nun weitere unbekannte Weine in Ihr Sortiment aufnehmen, markieren Sie erst alle Weine als bereits verköstigt.
sed -i -e 's/$/-bekannt/g' wein.txt
Nun ist die Markierung in allen Zeilen eingefügt – einschließlich der ersten Zeile, in der Sie die Spalten benennen. Um dies zu ändern, nehmen Sie noch eine Ersetzung in der ersten Zeile vor.
sed -i -e '1s/bekannt/Verköstigt/' wein.txt
Alternativen zu SED
Linux SED ist ein kraftvoller Befehl, mit dem Sie viele verschiedene Aufgaben erledigen können. Manches lässt sich allerdings nur sehr umständlich und mit ein paar Kniffen lösen. Mit ähnlichen Befehlen können Sie dann vielleicht schneller und sicherer ans Ziel gelangen.
AWK
Als Weiterentwicklung von SED hat sich AWK etabliert. Auch bei diesem Befehl arbeitet man mit regulären Ausdrücken, hat aber zusätzlich Möglichkeiten, die man aus komplexeren Programmiersprachen kennt. So können Sie mit AWK auch Befehle zusammenstellen, die If-Else-Anweisungen oder While-Do-Schleifen beinhalten.
PERL
Während sich AWK in erster Linie an C-Sprachen orientiert, gibt es auch einen Befehl, der auf Basis von PERL funktioniert. Zwar lassen sich mit der Sprache auch komplexe Systeme erstellen, aber für kleinere Aufgaben innerhalb des Terminals oder in Bash-Skripten ist PERL ebenfalls geeignet.
TR
Wenn Sie einzelne Zeichen in einer Textdatei umwandeln möchten, geht dies unter Umständen mit einem anderen Befehl als SED einfacher: TR (kurz für: translate) ist darauf ausgelegt, Buchstaben, Ziffern oder Sonderzeichen durch andere zu ersetzen. So lassen sich beispielsweise schnell doppelte Leerzeichen entfernen oder Groß-/Kleinschreibung anpassen. Während solche kleineren Aufgaben mit TR sehr einfach zu erledigen sind, müssen für komplexere Arbeiten andere Lösungen wie SED herangezogen werden.