Workshop: Einführung in den Stream-Editor Sed

Aus LinuxUser 08/2015

Workshop: Einführung in den Stream-Editor Sed

© zefart, 123RF

Am Fließband

Mit Sed editieren Sie Textdaten ohne interaktive Benutzeroberfläche – auch in Pipes oder der Eingabeumlenkung. In einer einzigen Zeile lassen sich umfangreiche Editierkommandos absetzen.

Mit dem Stream-Editor Sed [1] bearbeiten Sie Textdateien ohne einen ausgewachsenen Editor. Seine Stärken spielt er insbesondere bei sich wiederholenden Bearbeitungsvorgängen aus, die sich mithilfe von Shell-Skripten automatisieren lassen. Mit regulären Ausdrücken (Englisch: “regular expressions”) steht dem Kommandozeileneditor ein mächtiges Werkzeug zur Seite. Hier übergeben Sie dem Editor eine Beschreibung der Beschaffenheit der zu bearbeitenden Zeichenkette, sodass dieser große Textbestände ohne Zutun automatisiert abarbeitet.

Programmaufruf

Sed nimmt von allen Ecken Kommandos und Daten entgegen: Sie hängen diese entweder an den Aufruf an oder lassen Sed die gewünschten Kommandos aus einer Datei auslesen. Die zu bearbeitenden Daten kommen entweder per Pipe, Eingabeumlenkung oder direkt aus einer Textdatei. Die Ausgabe erfolgt entweder auf auf die Standardausgabe STDOUT (also in der Regel den Bildschirm), per Pipe an den nächsten Befehl oder durch Ausgabeumlenkung in eine Zieldatei. Sed selbst überschreibt hingegen in den Ausgangsdaten nichts.

Listing 1 zeigt eine Reihe von allgemeinen Beispielen. In Zeile 1 liest Sed eine Textdatei ein und gibt das Ergebnis auf der Standardausgabe aus. Im Zeile 2 geschieht dasselbe, allerdings mit Eingabeumlenkung. Zeile 3 zeigt das Anhängen von Sed per Pipe an die Ausgabe eines Programms. In Zeile 4 liest Sed sämtliche Anweisungen aus einer eigens für ihn erstellten Skript-Datei; alternativ geben Sie Sed mehrere Kommandos mit (Zeile 5).

In einigen Fällen wirkt sich die Reihenfolge der Befehle auf das Ergebnis aus. Testen Sie in daher in jedem Fall die Skripte ausgiebig, bevor Sie sie der auf den Datenbestand loslassen. In den Zeilen 6 und 7 leitet Sed seine Ausgabe in eine Zieldatei weiter, wobei im letzten Beispiel auch etwaige Fehlermeldungen dort landen.

Listing 1

$ sed Kommando Textdatei
$ sed Kommando < Textdatei
$ Programm | sed Kommando | ...
$ sed -f Skript ...
$ sed -e Kommando1 -e Kommando2 ... -e KommandoN Textdatei
$ sed Kommando > Zieldatei
$ sed Kommando > Zieldatei 2>&1

Syntax

Sed benötigt für das Editorkommando immer eine oder mehrere Adressen, auf die er das Kommando anwendet, wobei die grundlegende Syntax folgendermaßen aussieht:

$ sed [-Optionen] [Adresse[, weitere Adressen]] [!] Kommando [Argumente]

Als Adressen dienen oft Zeilennummern, wobei $ für die letzte Zeile steht, oder auch reguläre Ausdrücke (/.../). Sed nimmt beliebig viele Adressen entgegen, sofern Sie dabei nicht die Übersicht verlieren. Soll Sed an allen Textstellen außer den adressierten Passagen aktiv werden, kehren Sie eine Adressierung mittels ! einfach um (Negierung). Die Optionen zu Sed und seinen Editierkommandos finden Sie im weiteren Verlauf des Beitrages.

Um mehrere Sed-Kommandos auf einem Rutsch auszuführen, nutzen Sie am besten Sed-Skripte. Diese bestehen aus genau einer Zeile pro Anweisung (Listing 2). Möchten Sie das Skript von der Kommandozeile direkt ausführen, geben Sie /bin/sed in der ersten Zeile als Interpreter-Anweisung (“Shebang”) vor. Die Erste der zwei folgenden Anweisungen entfernt zuerst das Wort “Gans”. Genauer gesagt, tauscht die Anweisung das Wort gegen nichts aus. Die zweite Anwendung ersetzt bei jedem Vorkommen (Option g am Ende der Anweisung) den String “jo” gegen “Jo”.

Listing 2

#!/bin/sed -f
s/Gans//
s/jo/Jo/g

Machen Sie das Skript ausführbar (etwa über chmod +x Skript), dann lässt es sich wie jedes andere Programm oder Skript direkt von der Kommandozeile aus – ohne das Sed-Kommando davor – aufrufen. Im Regelfall nehmen Sie von dieser Möglichkeit jedoch selten Gebrauch. Vielmehr bringen Sie sed und eventuelle Aufrufe von Skript-Dateien in einem Shell-Skript unter.

Beispieldaten

Für erste Übungen nutzen Sie die in Listing 3 dargestellte Telefonliste. Speichern Sie den Inhalt dieser Tabelle in textdatei.txt ab. Die Tabelle sieht bewusst etwas wüst und zusammengeflickt aus: Leerzeilen, Rechtschreibfehler und andere Makel verunzieren sie. Mit Sed lassen sich diese Fehler jedoch leicht korrigieren – eine große Arbeitserleichterung, besonders dann, wenn es eine Datenbank mit mehreren Tausend Einträgen zu pflegen gilt. Die zweite Spielwiese in Listing 4 beinhaltet eine Liste mit grob unterschiedlich geschriebene Datumsangaben. Auch diese normiert Sed im Handumdrehen. Speichern Sie den Inhalt für den weiteren Gebrauch unter testliste.txt ab.

Listing 3

johann johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655

Listing 4

22 April 1984
 7.04.1985
30 März 1986
19 April 1987
03.04.1988
26 März 1989
15 April 1990
31-März-1991
19 April 1992
11 April 1993
 3 April 1994
16. April 1995
 7 April 1996
30 März 1997
12 April 1998

Reguläre Ausdrücke

Beim Ausführen von Sed-Befehlen kommen sehr oft reguläre Ausdrücke zum Einsatz, um Zeichenausdrücke aus dem Text herauszufiltern. Selbst wenn Sie den Ausdruck bisher noch nicht kennen, kennen Sie höchstwahrscheinlich reguläre Ausdrücke schon und nutzen sie regelmäßig: Wildcards wie in ls *.txt entsprechen einem regulären Ausdruck, und Texteditoren bieten über die Suchen-und-Ersetzen-Funktion oft eine Implementation für reguläre Ausdrücke.

In der Regel machen reguläre Ausdrücke jedoch deutlich mehr Arbeit. Mit ein wenig Logik bekommen Sie einfachere Ausdrücke allerdings gut in den Griff. Eine einfache Anweisung lautet zum Beispiel [ABC], sie prüft ob der String auf A, B oder C lautet. Das Konstrukt /ABC/ filtert hingegen auf den zusammenhängenden Begriff “ABC”. Den Aufbau und den Gebrauch regulärer Ausdrücke vollständig zu erklären, würde den Umfang dieses Artikels sprengen, daher finden Sie auf der beiliegenden Heft-DVD einen Artikel zu ersten Schritten mit Regular Expressions aus LinuxUser 06/2015 [2].

Zu so viel Macht reguläre Ausrücke Sed auch verhelfen, so unübersichtlich wachsen die Anweisungen komplexer Aufgaben. Hier hilft oft der Einsatz von Sed-Skripten, die die Aufgabe in mehrere Teile aufspalten. Einige Zeichen innerhalb der Konstrukte gelten zudem sowohl als Sonderzeichen der Shell als auch als Anweisungen für die regulären Ausdrücke. Sie müssen diese deshalb mit dem Zeichen \ für die Shell entwerten oder auf neuhochdeutsch “escapen” (siehe Tabelle “Sonderzeichen”).

Sonderzeichen

Zeichen Hinweis Sed-Funktionalität
( öffnet eine Anweisung
) schließt die Anweisung
{ öffnet optionale Anweisung
} schließt optionale Anweisung
[ öffnet Klassenbeschreibung von Zeichen
] schließt Klassenbeschreibung von Zeichen
" maskiert Anweisung und löst Shell-Variable auf
' maskiert eine Anweisung, löst Shell-Variable nicht auf
` schließt Anweisungsblock ein
. ein beliebiges Zeichen außer Zeilenvorschub
, trennt Parameter, etwa Zeilenangaben
Leerzeichen Setzt Markierung (t– und b-Befehl)
$ Dokumentenende, letzte Zeile oder Zeilenende
& Platzhalter für Suchmuster, welches in der Ersetzen-Anweisung mit ausgegeben wird
| oder (Abtrennen von regulären Ausdrücken)
/ Trennzeichen in Editierkommandos
^ Anfang der Zeile, aber: [^Begriff] = Negierung
\ Entwerter
! nach Zeilenzahl: nicht diese Zeile ausgeben
* nie oder beliebig oft
+ Muster mindestens einmal vorhanden
= Ausgabe der Zeilennummer
\n neue Zeile, Zeilenvorschub
\t Tabulator

Optionen und Kommandos

Verwirrenderweise verfügen sowohl Sed (siehe Tabelle “Sed-Optionen”) als auch die internen Editierkommandos (Tabelle “Editierkommandos”) über eigene Optionen. Wie im Linux-Leben allgemein üblich, teilen Sie dem Stream-Editor die Optionen mit vorangestelltem Minus-Zeichen mit. Den Editieranweisungen übergeben Sie ihre Optionen am Ende des Aufrufs (Tabelle “Optionen der Editierkommandos”).

Sed-Optionen

Aktion Option
Angabe auszuführender Befehle (Angabe meist unnötig) -e
Auf Datenpufferung verzichten -u
Dateien separat behandeln -s
Erweiterte reguläre Ausdrücke verwenden -r
Sicherungsdatei anlegen -i[Endung]
Skript-Datei einlesen und ausführen -f Skript
Unterdrücken der (nicht betroffenen) Textbereiche -n
Versionsabfrage -v

Editierkommandos

Aktion Kommando
Anfügen von Zeilen oberhalb der angegebenen Stelle i
Anfügen von Zeilen unterhalb der angegebenen Stelle a
Ausgabe der angegebenen Zeilen p
Ausgabe der angegebenen Zeilen optional mit Längenbegrenzung l [Länge]
Austausch von Zeichen y
Sed beenden q
Ersetzen von Text in der angegebenen Zeile c
Löschen der angegebenen Zeilen d
Suchen und Ersetzen s

Optionen der Editierkommandos

Aktion Option
Ausgabe der Zeilennummer =
Betrifft alle Vorkommen g
Gibt beim Editierkommando s die geänderte Zeile aus p
Schreiben der bearbeiteter Zeilen in die Datei w

Die Suchfunktion benötigen Sie unter anderem für das Ersetzen von Textteilen. Die Suchangabe stellt hierbei die Adressierung dar. Mithilfe der bereits angesprochenen regulären Ausdrücke erweitern sie die Angaben um Suchmuster. Die Tabelle “Suchmuster und Adressangaben” zeigt als Grundlage eine kleine Auswahl der Möglichkeiten. Einige Praxisbeispiele finden Sie in der Tabelle “Beispielsuchen und Suchmuster”. Sie enthält Fälle, in denen Sed ein Teil des Datenstrom darstellt, als auch Situationen, in denen Sed direkt auf eine Textdatei zugreift.

Suchmuster und Adressangaben

Aktion Muster
Alle Zeilen (ohne)
Zeile 25 25
Nicht Zeile 25 25!
Zeilen 10 bis 20 10,20
Letzte Zeile $
Nicht Suchmuster '/Muster/!'
Zeichen am Zeilenanfang ^Zeichen
Zeichenkette /Zeichenkette/
Zeichenmenge [Zeichenmenge]
beliebige Buchstaben [:alpha:]
Kleinbuchstaben [:lower:]
Großbuchstaben [:upper:]
alphanumerische Zeichen [:alnum:]
Zahlen [:digit:]
Hexadezimalzahlen [:xdigit:]
Tabulatoren und Leerzeichen [:blank:]
Leerzeichen [:space:]
Steuerzeichen [:cntrl:]
Druckbare Zeichen (ohne Steuerzeichen) [:print:]
Sichtbare Zeichen (ohne Leertaste) [:graph:]
Satzzeichen [:punct:]

Beispielsuchen und Suchmuster

Gesucht Suchmuster Beispiel Listing
Begriff, Name '/Begriff/' cat textdatei.txt | sed -n '/Meier/p'
alle Namen, die “han” oder “Han” beinhalten '/[Hh]an/p' sed -n '/[Hh]an/p' textdatei.txt 5
Alle Zeilen außer 3 bis 5 '3,5!' sed -n '3,5!'p textdatei.txt 6
Alle Zeilen, die nicht “Gans” enthalten '/Gans/!' sed -n '/Gans/!'p textdatei.txt 7
Zeilen, die “H” oder “G” enthalten '/[H|G]/' sed -n '/[H|G]/'p textdatei.txt
Zeilen, die “H” oder “G” nicht enthalten '/[H]\|[G]/!' sed -n '/[H]\|[G]/!'p textdatei.txt 8
Zeile 3 3 cat textdatei.txt | sed -n '3p'
Letzte Zeile '$p' cat textdatei.txt | sed -n '$p'
Zeilen nicht ausgeben, die “H” und in der Folge “J” enthalten '/[H]./,/[J]./!' sed -n '/[H]./,/[J]./!'p textdatei.txt 9
Alle Zeilen, die alphanumerische Zeichen enthalten (Leerzeilen unterdrücken) '/[:alnum:]/' cat textdatei.txt | sed -n '/[:alnum:]/'p 10

Bei zusammengesetzten Adressangaben (ab zwei Suchmustern) verarbeitet Sed alle Zeilen außer der ersten, auf die die erste Adresse zutrifft, bis einschließlich der nächsten Zeile, auf die die zweite Adresse passt. Beachten Sie hierbei das Beispiel aus Listing 9: In der Textdatei textdatei.txt steht ein Eintrag mit kleinem “j” vor dem mit “J”. Das entsprechende Sed-Kommando aus Tabelle “Beispielsuchen und Suchmuster” soll alle Zeilen ausgeben, die “H” und “J” enthalten. In diesem Fall funktioniert das, da die Reihenfolgen im Befehl und in der Textdatei übereinstimmen. Das zweite Beispiel mit den negierten Zeichen “H” und “j” zeigt aber, dass Sed zuerst eine Zeile mit “H” finden muss. Daher gibt Sed den “johann” aus der ersten Zeile trotz des Suchfilters aus.

Listing 5

$ sed -n '/[Hh]an/p' textdatei.txt
johann johannson  0885465468798746
Hans Michael  0987654321
Jochen Hansen  0405458765143321

Listing 6

$ sed -n '3,5!'p textdatei.txt
johann johannson  0885465468798746
Gabi Gans Meier   0548/9988776655

Listing 7

$ sed -n '/Gans/!'p textdatei.txt
johann johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321

Listing 8

$ sed -n '/[H]\|[G]/!'p textdatei.txt
johann johannson  0885465468798746
Klaus Schraube  08755466584

Listing 9

$ sed -n '/[H]./,/[J]./!'p textdatei.txt
johann johannson  0885465468798746
Klaus Schraube  08755466584
Gabi Gans Meier   0548/9988776655
$ sed -n '/[H]./,/[j]./!'p textdatei.txt
johann johannson  0885465468798746
Klaus Schraube  08755466584

Listing 10

$ cat textdatei.txt | sed -n '/[:alnum:]/'p
johann johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655

Soll Sed in einem Rutsch mehr als nur einen Filter anwenden, hängen Sie die unterschiedlichen Aufrufe am einfachsten mit einer Pipe hintereinander (Listing 11). Das Kommando unterdrückt entsprechend Listing 10 leere Zeilen und filtert anschließend wie in Listing 7 alle Zeilen mit “Gans” aus der Ausgabe.

Listing 11

$ cat textdatei.txt | sed -n '/[:alnum:]/'p | sed -n '/Gans/!'p
johann johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321

Ersetzen und Löschen

Für das Ersetzen von Zeichenketten in den gefundenen Ausdrücken verwenden Sie die Anweisung s. Die Länge der Zeichenketten für das Suchen und Ersetzen ist dabei unerheblich. Die Syntax der Suchen-und-Ersetzen-Anweisung lautet folgendermaßen:

$ sed -n '[Zeile(n)]s/[Muster]/Ersatz/[Optionen_für_s]'
$ sed -n '[/Muster/]s/[Muster]/Ersatz/[Optionen_für_s]'

Der Schalter -n sorgt dafür, dass Sed nur bearbeitete Zeilen ausgibt; das Muster ist optional, wenn Befehl nur auf bestimmte Zeilen angewendet werden soll. Die Tabelle “Optionen für s” führt die entsprechenden Optionen auf.

Optionen für <c>s<c>

Option Beschreibung
g Befehl auf alle gefundenen Textstellen in der Zeile anwenden
p Ergebnis der Aktionen ausgeben
w[Datei] Ergebnis in eine Datei schreiben

Die Suchen-und-Ersetzen-Anweisung beschränken Sie auf bestimmte Zeilennummern, indem Sie vor dem Kommando den Bereich in der Form 5s/Alt/Neu/p (Listing 12, Zeile 1) für eine einzelne Zeile oder in Form von 1,4/Alt/Neu/p (Zeile 2) einen Bereich angeben. Mit einem Ausrufezeichen kehren Sie die Auswahl um (Zeile 3). Weiterhin lässt sich die Anweisung unabhängig von der Suchen- beziehungsweise Ersetzen-Vorschrift auf Zeilen beschränken, die eine bestimmte Zeichenkette oder Struktur aufweisen (Zeile 4). Möchten Sie die gesuchte Zeichenkette gleich löschen, dann geben Sie Sed eine leere Ersetzungsanweisung mit.

Listing 12

$ sed -n '5s/Alt/Neu/p' [Datei]
$ sed -n '1,4/Alt/Neu/p' [Datei]
$ sed -n '20-80!s/Alt/Neu/p' [Datei]
$ sed -n '/[Zeichenkette|Muster]/s/Alt/Neu/gp' [Datei]

Grundsätzlich bearbeitet Sed jeweils das erste Auftreten des Suchmusters in einer Zeile. Soll der Editor jedoch an alle passenden Fundstellen Hand anlegen, fügen Sie am Ende der Anweisung die Option g (wie “gesamt”) hinzu. Im Normalfall gibt Sed Feedback zu den jeweiligen Arbeitsschritten aus. Diese Ausgabe unterdrücken Sie mit der Option -n und verwandeln den Stream-Editor so in einen stummen Diener. Gesprächiger wird Sed hingegen mit der Option p wie (“print”). Alternativ schreiben Sie die Ergebnisse in eine neue Ausgabedatei. Zusammen mit der Option w geben Sie eine Zieldatei an. Die Tabelle “Beispiele: Suchen und Ersetzen” zeigt einige kürzere Beispiele.

Beispiele: Suchen und Ersetzen

Aktion Beispiel Listing
Suchmuster nur beim ersten Auftreten ersetzen cat textdatei.txt | sed -n 's/j/J/p' 13
Suchmuster bei jedem Auftreten ersetzen cat textdatei.txt | sed -n 's/j/J/gp' 13
Löschen des Wortes “Gans” sed -n 's/Gans//gp' textdatei.txt 14
Ersetzen von “Hans” durch “Jens” in der Zeile 4 cat textdatei.txt | sed -n '4s/Hans/Jens/gp' 15
Ersetzen von “09” durch “089” bei allen Zeilen mit der Zeichenkette “ans” sed -n '/ans/s/09/089/gp' textdatei.txt 16
Ersetzen von “0” durch “089” bei allen Zeilen, außer sie enthalten die Zeichenkette “ans” sed -n '/ans/!s/0/089/gp' textdatei.txt 17
Löschen aller Zahlen mitsamt Schrägstrichen cat textdatei.txt | sed -n s'/[0-9\/]//'gp 18

Listing 13

$ cat textdatei.txt | sed -n 's/j/J/p'
Johann johannson  0885465468798746
$ cat textdatei.txt | sed -n 's/j/J/gp'
Johann Johannson  0885465468798746

Listing 14

$ sed -n 's/Gans//gp' textdatei.txt
Gabi  Meier   0548/9988776655

Listing 15

$ cat textdatei.txt | sed -n '4s/Hans/Jens/gp'
Jens Michael  0987654321

Listing 16

$ sed -n '/ans/s/09/089/gp' textdatei.txt
Hans Michael  08987654321

Listing 17

$ sed -n '/ans/!s/0/089/gp' textdatei.txt
johann johannson  089885465468798746
Klaus Schraube  0898755466584

Listing 18

$ cat textdatei.txt | sed -n s'/[0-9\/]//'gp
johann johannson
Klaus Schraube
Hans Michael
Jochen Hansen
Gabi Gans Meier

Ein komplexeres Beispiel finden Sie in Listing 19. Die über mehrere Zeilen per Pipe verknüpften Sed-Aufrufe bringen die uneinheitlich geschriebenen Datumsangaben aus der Datei testliste.txt in eine normierte Form. Beim Eingeben eines solchen Kettenbefehls müssen Sie darauf achten, nach dem Rückstrich \ am Ende die Zeile sofort umzubrechen und nicht noch ein Leerzeichen anzuhängen. Alternativ lassen Sie den Zeilenumbruch weg und fahren umgehend mit dem Pipe-Zeichen der Folgezeile fort.

Listing 19

$ cat testliste.txt \| sed '/^[\ ]/'s'/\ /0/'p \| sed s'/-/ /'pg \| sed s'/März/03./'p \| sed s'/April/04./'p \| sed s'/^\([0-3][0-9]\ \)/&./'p \| sed s'/\ //'gp \| uniq
22.04.1984
07.04.1985
30.03.1986
[...]

Der Aufruf von cat in Zeile 1 liest die Liste aus der Datei aus und füttert sie am am Anfang von Zeile 2 in die Pipe. Das erste Sed-Kommando in Zeile 2 ersetzt führende Leerzeichen durch die Ziffer “0”. Zeile 3 tauscht Minuszeichen in den Datumsangaben gegen Leerzeichen. Die Aufrufe von Sed in den Zeilen 4 und 5 ersetzen nun den in Worten geschriebenen Monat durch den passenden numerischen Wert und hängen einen Punkt an – für ein vollständiges Kalender-Skript müssten Sie dies für jeden Kalendermonat erledigen.

Die Anweisung in Zeile 6 ist nun nicht mehr ganz so einfach zu durchblicken. Sie ersetzt alle am Zeilenanfang stehenden (^), zweistelligen Zahlen (die erste Stelle mit Ziffern von 0 bis 3, die zweite Stelle mit allen Ziffern) und einem Leerzeichen durch sich selbst (&) und einen Punkt. Damit die Wiederholung des Suchbegriffs für das Ersetzen funktioniert, setzen Sie den Bereich in runde Klammern, die Sie allerdings mit einem Backslash \ entwerten müssen.

Die Sed-Anweisung der Zeile 7 entfernt nun sämtliche Leerzeichen (g als Option von s) aus dem restlichen Text. Mit uniq aus Zeile 8 entfernen Sie am Ende noch jede mehrfach aufeinander folgende, zum Vorgänger identische Zeile, sodass Sie nun eine sauber normierte und formatierte Liste mit Datumsangaben erhalten.

Das Übernehmen des zu ersetzenden Musters in den Ersatzbegriff erspart in der Praxis viel Arbeit, daher macht ein etwas ausführlicherer Blick auf diese Funktion Sinn. Das Sed-Kommando aus der ersten Zeile von Listing 20 macht aus “schraube” das Wort “abschrauben”. Ähnlich funktioniert das Umwandeln von Klein- in Großbuchstaben (Zeile 3). Das \U vor & signalisiert die Anweisung für die Ausgabe in Großbuchstaben. Für den umgekehrten Weg verwenden Sie zum Suchen [[:upper:]] und die Anweisung \L. Beide Beispiele kombiniert ergeben dann aus dem orthografisch korrekten Hauptwort “Schraube” das Verb “abschrauben” (Zeile 9).

Listing 20

$ echo "schraube" | sed -n s'/schraube/ab&n/'p
abschrauben
$ cat textdatei.txt | sed -n s'/\([[:lower:]]\)/\U&/'pg
JOHANN JOHANNSON  0885465468798746
KLAUS SCHRAUBE  08755466584
HANS MICHAEL  0987654321
JOCHEN HANSEN  0405458765143321
GABI GANS MEIER   0548/9988776655
$ echo "Schraube" | sed -n s'/Schraube/ab&n/'p | sed -n s'/\([[:upper:]]\)/\L&/'pg
abschrauben

Für Zeichenfilter und andere Anwendungen verwenden Sie diese Option y. Führen Sie in diesem Fall im Suchmuster-Teil alle Zeichen einzeln auf, die Sed austauschen soll. Der Ersetzen-Teil sollte aus der selben Anzahl an Zeichen bestehen. Der Kommandoaufbau kennt keine weiteren Optionen, auch sollten Sie -n weglassen. Das einfache Beispiel sed y'/a/b/' würde etwa sämtliche “a” im Text gegen “b” tauschen.

Listing 21 wendet die Option in einem etwas komplexeren Beispiel auf textdatei.txt an. Das Kommando ersetzt in allen Zeilen, die mit “j” beginnen, kleine “j” durch den Großbuchstaben. Dabei gilt es aber darauf zu achten, dass Sed in diesem Fall den Buchstaben auch innerhalb eines Wortes in einen Großbuchstaben verwandeln würde.

Listing 21

$ cat textdatei.txt | sed '/^j/'y'/j/J/'
Johann Johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655

Komplette Zeilen

Beim Austausch einer kompletten Zeilen greifen Sie auf die Sed-Option c zurück. Allgemein tauschen Sie mit sed 'Suche'c'Ersatz' die über den Suchbegriff herausgefilterte Zeile vollständig gegen den Ersatzbegriff aus. Das Beispiel aus Listing 22 löscht die Leerzeile und trägt stattdessen einen Trenner in Form einer Reihe von Minuszeichen ein.

Listing 22

$ cat textdatei.txt | sed '/^\ *$/'c'---'
johann johannson  0885465468798746
---
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655

Anstelle des Suchmusters nimmt Sed allgemein mit sed [Zeile(n)]c'Ersatz' an dieser Stelle auch Zeilennummern an. Das erste Beispiel aus Listing 23 ersetzt die Leerzeile in Zeile 2 von textdatei.txt durch einen Balken mit Rauten. Beachten Sie bei der Angabe mehrerer Zeilennummern, dass Sie diese und alle anderen aus diesem Bereich löschen und mit der Austauschzeile ersetzen. Das Beispiel aus Zeile 8 löscht die Zeilen 2 bis 4 aus dem Inhalt von textdatei.txt und setzt an deren Stelle den Ersatztext ein.

Listing 23

$ cat textdatei.txt | sed 2c'###'
johann johannson  0885465468798746
###
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655
$ cat textdatei.txt | sed 2,4c'Restliche Mitglieder'
johann johannson  0885465468798746
Restliche Mitglieder
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655

Soll Sed gleich ganze Zeilen aus dem Inhalt entfernen, verwenden Sie die Sed-Option d. Die zu löschenden Zeilen sprechen Sie über ein Suchmuster an, wie etwa sed '/Muster/'d. Alternativ geben Sie direkt die Zeilennummer(n) der nicht mehr erwünschten Zeilen an: sed Zeile(n)d. Die Beispiele aus Listing 24 löschen die Leerzeile aus textdatei.txt oder entfernen ohne weitere Umwege die vierte Zeile aus dem Inhalt.

Listing 24

$ cat textdatei.txt | sed '/^\ *$/'d
johann johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655
$ cat textdatei.txt | sed 4d
johann johannson  0885465468798746
Klaus Schraube  08755466584
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655

Inhalte einfügen

Mit der Anweisung a fügen Sie zusätzliche Zeilen unterhalb, mit i oberhalb der angegeben Zeile oder des Suchmusters ein. Für die Positionierung nutzen Sie ein Suchmuster oder geben direkt eine Zeilennummer an. Führen Sie mehrere Zeilennummern an oder passt das Suchmuster gleich auf mehrere Zeilen, wendet Sed die Anweisung auf jede passende Zeile an.

Listing 25 zeigt zwei Beispiele zum Einfügen von Inhalten: Das erste Kommando ab Zeile 1 fügt am am Anfang und am Ende der Ausgabe (definiert über $) jeweils eine neue Zeile ein. Das Kommando ab Zeile 12 sucht hingegen nach dem String “Gans” und fügt dann um diesen herum jeweils die vorbereitete Textzeile ein. In der Praxis erstellen Sie so zum Beispiel manuell zu bearbeitende Prüflisten.

Listing 25

$ cat textdatei.txt \| sed '1i NEU ERSTE ZEILE NEU'\| sed '$a NEU LETZTE ZEILE NEU'
NEU ERSTE ZEILE NEU
johann johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
Gabi Gans Meier   0548/9988776655
NEU LETZTE ZEILE NEU
$ sed '/Gans/'i'---- DATEN ÜBERPRÜFEN ----' textdatei.txt\| sed '/Gans/'a'----'
johann johannson  0885465468798746
Klaus Schraube  08755466584
Hans Michael  0987654321
Jochen Hansen  0405458765143321
---- DATEN ÜBERPRÜFEN ----
Gabi Gans Meier   0548/9988776655
----

Soll Sed per Skript eine Shell-Variable entgegennehmen und korrekt auflösen, müssen Sie die Anweisungen in Anführungszeichen (") anstelle eines Hochkommas (') setzen. Das kleine Shell-Skript in Listing 26 zeigt exemplarisch die Handhabung von Shell-Variablen. Es fragt per read einen Suchbegriff ab und durchforstet anschließend textdatei.txt nach diesem String. Listing 27 zeigt den Ablauf des Skripts im Terminal.

Listing 26

#! /bin/sh
echo -n "Suchbegriff eingeben: "; read eingabe
cat textdatei.txt | sed -n "/$eingabe/"p

Listing 27

$ ./musterskript.sh
Suchbegriff eingeben: Hansen
Jochen Hansen  0405458765143321

Fazit

Mit Sed gelingen Textmanipulationen ohne Benutzereingriff vollautomatisch. Eine durchaus kryptische Syntax erschwert anfangs den schnellen Gebrauch. Bauen Sie deshalb Ihre Skripte schrittweise auf. 

Infos

[1] Projektseite: http://sed.sourceforge.net/

[2] Regular Expressions: Frank Hofmann, “Schnipseljagd”, LU 06/2015, S. 10, http://linux-community.de/35006

Der Autor

Harald Zisler beschäftigt sich seit den frühen 90er-Jahren mit FreeBSD und Linux. Zu Technik- und EDV-Themen verfasst er Zeitschriftenbeiträge und Bücher. Aktuell hat er beim Rheinwerk-Verlag die dritte Auflage von “Computer-Netzwerke” veröffentlicht.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 08/2015 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben