Sed
Linux- Stream Editor – sed
Einführung
- sed is a “non-interactive” stream-oriented editor. Since its an “non-interactive” it can be used to automate editing if desired.
- The name sed is an abbreviation for stream editor, and the utility derives many of its commands from the ed line-editor (ed was the first UNIX text editor).
- This allows you to edit multiple files, or to perform common editing operations without ever having to open vi or emacs.
- sed reads from a file or from its standard input, and outputs to its standard output.
- sed has two buffers which are called pattern buffer and hold buffer. Both are initially empty.
Arbeitsweiseaus regex-skript
Print the pattern buffer to stdout. Der Stream Editor ist kein herkömmlicher Editor wie Vi oder Emacs. Sed arbeitet nicht interaktiv; er wird mittels Kommandozeilenoptionen oder durch ein Skript gesteuert.
Sed modifiziert nicht 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.
Unix Sed Working methodology
This is called as one execution cycle. Cycle continues till end of file/input is reached.# Read a entire line from stdin/file.
- Removes any trailing newline.
- Places the line, in its pattern buffer.
- Modify the pattern buffer according to the supplied commands.
Aufruf
Der Aufruf des Stream Editors auf der Kommandozeile besitzt immer folgendes Format:
sed 'Kommando' Dateiname
Wenn man sed eine Variable übergeben möchte, eignet sich die Verwendung von doppelten Anführungszeichen. Das ist vor allem in Skripten oft der Fall.
sed "Kommando mit $Variable" Dateiname
Das hängt damit zusammen, dass die Bash den Inhalt von einfachen Anführungszeichen als reinen Text versteht. Inhalt der doppelten Anführungszeichen jedoch wird auf Sonderbedeutung überprüft.
Die doppelten Anführungszeichen haben aber auch zu Folge, dass man das $-Zeichen bei der Adressierung nicht einfach so verwenden kann.
Um die Sonderbedeutung es $-Zeichen in doppelten Anführungszeichen aufzuheben, muss ein Backslash vorangestellt werden (\$).
sed arbeitet zeilenorientiert, d.h. es liest die Eingabedatei Zeile pro Zeile und wendet auf jede Zeile den bzw. die Befehle an. Eine Zeile endet dort, wo das Zeichen "linefeed", also 0x0A steht.
Dateiübergabe an sed
Output von cat als Input von sed
cat sed-test-txt | sed [anweisungen...]
Umleitung von Stdin
sed [anweisungen...] < sed-test.txt
Dateiname als Kommandozeilenparamter
sed [anweisungen...] sed-test.txt
Ausgabe
Die Ausgabe erfolgt nach Stdout, also auf den Bildschirm. Sie kann mittels Pipe-Symbol an andere Kommandos übergeben oder in eine Datei umgeleitet werden:
Stdout ist Stdin für "less"
cat sed-test-txt | sed [anweisungen...] | less
Umleitung in Datei
cat sed-test-txt | sed [anweisungen...] > output.txt
Kommandoübersicht
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 | Fügt eine oder mehrere Zeilen an die aktuelle Zeile an |
c | Ersetzt Text in der aktuellen Zeile |
d | Löscht Zeile(n) |
g | Kopiert den Inhalt eines temporären Puffers in den Arbeitspuffer (dessen alter Inhalt geht verloren) |
G | Fügt den Inhalt eines temporären Puffers an den Inhalt des Arbeitspuffers an |
h | Kopiert den Inhalt des Arbeitspuffers in einen temporären Puffer |
H | Fügt den Inhalt des Arbeitspuffers an einen temporären Puffer an |
i | Fügt Text oberhalb der aktuellen Zeile ein |
l | Zeigt nicht druckbare Zeichen an |
n | Wendet das nächste Kommando anstelle des aktuellen Kommandos auf die nächste Zeile an |
p | Druckt Zeile(n) |
q | Beendet den Editor |
r | Liest Zeilen aus einer Datei |
! | Wendet das Kommando auf Zeilen an, die nicht zutreffen |
Substitutionen
Im Zusammenhang mit Substitutionen werden die Kommandos häufig als Flags bezeichnet.
Die Wirkung mancher Kommandos (»g«) wird aus dem Kontext entschieden wird.
g | Globale Ersetzung (jedes Vorkommen des Musters auf der Zeile) |
p | Ausgabe der Zeile in Verbindung mit "s". |
s | Ersetzen eines Musters durch ein anderes |
w | Ausgabe der bearbeiteten Zeilen in eine Datei |
x | Austausch des Inhalts des Zwischenspeichers mit der aktuell bearbeiteten Zeile |
y | Ersetzen eines Zeichens durch ein anderes |
Reguläre Ausdrücke
Folgende Reguläre Ausdrücke werden von sed unterstützt
^ | Zeilenanfang |
$ | Zeilenende (bei der Adressierung steht das Zeichen für die letzte Zeile) |
. | Ein Zeichen (Ausnahme ist der Zeilenumbruch) |
* | Keine, eine oder mehrere Wiederholungen des vorhergehenden Buchstabens / der vorhergehenden Gruppe |
[...] | Ein Zeichen aus der Menge |
[^...] | Kein Zeichen aus der Menge |
\(...\) | Speichern des enthaltenen Musters |
& | Enthält das Suchmuster |
\< | Wortanfang |
\> | Wortende |
x\{m\} | m-fache Wiederholung des Zeichens x |
x\{m,\} | Mindestens m-fache Wiederholung des Zeichens x |
x\{m,n\} | Mindestens m-, maximal n-fache Wiederholung des Zeichens x |
Beispieltexte
Die Handhabung des Stream Editors erlernen Sie vermutlich nur durch Beispiele. Zunächst soll es um die Möglichkeiten zur Adressierung von Zeilen mit Sed gehen (das Schema lässt sich u.a. auch im Vi anwenden)
cat sedtest.txt
Der Aufruf des Stream Editors besitzt immer das Format: sed 'Kommando' Dateiname Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende Mechanismen in Frage: Keine Angabe Alle Zeilen Nummer Genau diese Zeile Start, Ende Alle Zeilen von "Start" bis "Ende" $ Symbolisiert die letzte Zeile RegEx Zeilen, die den Regulären Ausdruck enthalten 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Um die spätere Arbeit des Editors besser verfolgen zu können, nummerieren wir noch die Datei:
nl -w 2 -b a sedtest.txt | tee test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname 4 5 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der 6 Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende 7 Mechanismen in Frage: 8 9 Keine Angabe Alle Zeilen 10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Erstellung einer Testdatei
cat > sed-test.txt << EOF Dies ist Zeile 1 Hier isst ein Fehler Hier isst noch ein Frhler Dies ist die vorletzte Zeile Dies ist die letzte Zeile EOF
Exkurs: Zeilen nummerieren mit nlBeispiele einfügen
nl gibt die Zeilen einer oder mehrerer Dateien (oder der Standardeingabe) mit Zeilennummern auf die Standardausgabe.
Es können dabei die Zeilen einer (logischen) Seite in einen Kopf, einen Körper und einen Fuß unterteilt werden, die jeweils einzeln und in unterschiedlichen Stilen numeriert werden.
Jeder Teil kann auch leer sein. Wenn vor dem ersten Kopfteil bereits Zeilen vorhanden sind, werden diese Zeilen wie ein Seitenkörper numeriert.
Die Numerierung beginnt auf jeder Seite neu. Mehrere Dateien werden als ein einziges Dokument betrachtet und die Zeilennummer wird nicht zurückgesetzt.
Der Kopfteil wird durch eine Zeile eingeleitet, die nur die Zeichenkette `\:\:\:' enthält.
Der Körper wird entsprechend durch `\:\:' und der Fuß durch `\:' eingeleitet. In der Ausgabe werden diese Zeilen als Leerzeilen ausgegeben.
Optionen
-h Stil | bestimmt die Art der Zeilennumerierung für die Kopfzeile; das Nummerntrennzeichen wird auch den nicht numerierten Zeilen vorangestellt; als Stil werden folgende Zeichen erkannt
a alle Zeilen t leere Zeilen nicht (Voreinstellung für den Körper) n Zeilen werden nicht numeriert (Voreinstellung für Kopf und Fuß) p Ausdruck nur Zeilen, in denen der reguläre Ausdruck vorkommt, |
-b Stil | bestimmt die Art der Zeilennumerierung für den Körper |
-f Stil | bestimmt die Art der Zeilennumerierung für den Fuß |
-p | die Zeilen aller Seiten werden fortlaufend numeriert |
-v Nummer | die erste Zeile jeder logischen Seite bekommt die angegebene Nummer |
-i Nummer | die Schrittweite für die Numerierung |
-l Nummer | die angegebene Anzahl aufeinanderfolgender Leerzeilen werden als eine Zeile angesehen, und die letzte Zeile wird numeriert;
wenn weniger Leerzeilen in Folge auftreten, werden sie nicht numeriert; Leerzeilen dürfen keine Leerzeichen oder Tabulatoren enthalten |
-s Zeichenkette | setzt die Zeichenkette als Nummerntrennzeichen zwischen Zeilennummer und Text; Voreinstellung ist TAB |
-w Nummer | die Zeilennummern erhalten die angegebene Anzahl Stellen; Voreinstellung ist 6 |
-n {ln, rn, rz} | die Zeilennummern werden in dem angegebenen Stil ausgegeben; dabei bedeutet
ln linksbündig, ohne führende Nullen rn rechtsbündig, ohne führende Nullen rz rechtsbündig, mit Nullen auf die volle Stellenzahl aufgefüllt |
-d zwei Zeichen | die zwei Zeichen werden zur Trennung von Kopf, Körper und Fußteil benutzt, Voreinstellung ist `\:' |
Aufbau der sed-Anweisungen
Aber wenn man ein paar grundlegende Dinge verstanden hat, ist es nicht schwierig. Die sed-Anweisungen werden i.A. von einfachen Hochkommas umschlossen.
sed 'anweisung' < sed-test.txt
sed kann mehrere Anweisungen in einem Durchgang abarbeiten. In diesem Falle muss jedem Befehl die Option "-e" vorangestellt werden. Wenn nur eine Anweisung abgearbeitet werden soll, kann man "-e" weglassen.
sed -e 'anweisung1' -e 'anweisung2' < sed-test.txt
möglich, aber etwas unübersichtlicher ist auch diese Form:
sed -e 'anweisung1; anweisung2' < sed-test.txt
In vielen sed-Anweisungen kommt das Zeichen '/' vor. Es ist ein Begrenzungszeichen, also ein "delimiter". Eine Regular Expression, also ein Suchausdruck, wird durch zwei Schrägstriche begrenzt. Im folgende kürze ich "Regular Expression" durch "RE" ab.
Unvollständige Anweisung:
sed '/isst/' < sed-test.txt
- sed durchsucht die Datei Zeile pro Zeile nach dem String "isst"
- die RE "isst" wird durch "/" am Anfang und Ende eingegrenzt.
- "/" ist also nichts anderes als ein Begrenzungszeichen, ähnlich wie Hochkommata
Die vorige Anweisung ist unvollständig, da sie nur aus der RE '/isst/' besteht. sed muss noch mitgeteilt werden, wie mit dem Suchergebnis zu verfahren ist.
Hinter der durch die RE getroffenen Bereichsauswahl ist der Befehl anzugeben. Eine sed-Anweisung enthält also i.A. mindestens zwei Komponenten (die Bereichsauswahl kann in bestimmten Konstrukten fehlen): # Bereichsauswahl
Auswahl der Zeilen, die bearbeitet werden sollen. Im vorigen Beispiel würde sich die Auswahl auf alle Zeilen beziehen, in denen "isst" vorkommt.
- Befehl
Was soll mit den ausgewählten Zeilen passieren? Der einfachste Befehl lautet "p" (print), er gibt die selektierten Zeilen am Bildschirm aus.
Das vorige Beispiel wird vervollständigt:
sed '/isst/p' < sed-test.txt
- Durchsuchen der Datei nach Zeilen, die "isst" enthalten
- Die selektierten Zeilen werden am Bildschirm ausgegeben
- "/" umschließt die RE, hat also mit dem Befehl "p" nichts zu tun.
Leider liefert die sed-Anweisung ein unbefriedigendes Ergebnis, da alle Zeilen ausgegeben werden.
Dies liegt an der Arbeitsweise von sed. Um das gewünschte Ergebnis zu erhalten, muss sed mit der Option "-n" aufgerufen werden:
sed -n '/isst/p' < sed-test.txt
- beim p-Befehl immer die Option "-n" verwenden!
- aufgrund der Option "-n" werden nur die Zeilen ausgegeben, in denen "isst" vorkommt.
Wenn man die Option "-e" verwendet, muss beachtet weden, dass "-n" vor "-e" steht.
sed -n -e '/isst/p' < sed-test.txt
- "-e" muss hinter "-n" stehen!
Dateizeilen ausgeben
Ausgabe [p]
Zunächst wenden wir das Kommando p auf die ersten 3 Zeilen der Datei an:
sed '1,3p' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 1 Der Aufruf des Stream Editors besitzt immer das Format: 2 2 3 sed 'Kommando' Dateiname 3 sed 'Kommando' Dateiname 4 5 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der 6 Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende 7 Mechanismen in Frage: 8 9 Keine Angabe Alle Zeilen 10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
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.
Mehrfache Ausgaben unterbinden [-n]
Um solche »überflüssigen« Ausgaben zu unterbinden, muss die Option »-n« verwendet werden:
sed -n '1,3p' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname
Bei der Adressierung mittels regulärer Ausdrücke müssen diese in Schrägstriche (Slashes) eingeschlossen sein:
sed -n '/RegEx/,/RegEx/p' test.txt
13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Printing Operation in Sed
is a command for printing the data from the pattern buffer.
Adressierung
Es ist möglich, bestimmte Zeilen explizit auszuwählen, also z.B. "Zeile 1", "Zeile 1-2", "letzte Zeile" usw. In diesem Falle wird die Bereichsauswahl direkt angegeben, sie steht also nicht zwischen "/" wie bei RE-Ausdrücken.
Der Befehl 'p' steht direkt hinter der Bereichsauswahl.
Using Address and Patterns
from a file using sed address and patterns.
- will delete the pattern space buffer and immediately starts the next cycle.
Syntax
- sed 'ADDRESS'd filename
- sed /PATTERN/d filename
ADDRESS Format Beispiele
NUMBER
This will match only Nth line in the input.
# sed -n ‘N’p filename
For example, 3p prints third line of input file thegeekstuff.txt as shown below.
# sed -n '3'p thegeekstuff.txt 3. Hardware
Erste Zeile ausgeben
sed -n '1p' < sed-test.txt
Option "-n" nicht vergessen!
NUMBER1~NUMBER2
# sed -n ‘M~N’p filename
START, END
# sed -n ‘M,N’p filename
‘$’ Last Line
# sed -n ‘$’p filename
NUMBER,$
# sed -n ‘N,$p’ filename
Letzte Zeile ausgeben
sed -n '$p' < sed-test.txt
PATTERN Format Beispiele
PATTERN
# sed -n /PATTERN/p filename
/PATTERN/,ADDRESS
# sed -n ‘/PATTERN/,Np’ filename
ADDRESS,/PATTERN/
# sed -n ‘N,/PATTERN/p’ filename
/PATTERN/,$
# sed -n ‘/PATTERN/,$p’ filename
/PATTERN/,+N
# sed -n ‘/PATTERN/,+Np’ filename
/PATTERN/,/PATTERN/
# sed -n ‘/P1/,/P2/p’ filename
Besondere Zeichen
Negation
Das Ausrufezeichen ("!") hinter der Bereichsauswahl bewirkt eine Negation
sed '/isst/!d' < sed-test.txt
- Zeilen, die "isst" nicht enthalten, werden nicht ausgegeben
sed -n '1!p' < sed-test.txt
- alle Zeilen außer Zeile 1 werden ausgegeben
$-Zeichen: letztes Element
Das $-Zeichen steht bei der Bereichsauswahl für "letzte Zeile":
sed -n '$p' < sed-test.txt
- letzte Zeile ausgeben
In einer RE steht das $-Zeichen für "Zeilenende"
sed -n '/Zeile$/p' < sed-test.txt
- Zeilen ausgeben, in denen "Zeile" am Ende steht
Möchte man dem Zeilenende eine Zeichenkette anhängen, genügt ein $ als Suchmuster:
sed -n 's/$/ und Schluss!/p' < sed-test.txt
- Jede Zeile endet mit ' und Schluss!'
^ - Zeichen
Das ^-Zeichen steht in einer RE für Zeilenanfang:
sed -n '/^Hier/p' < sed-test.txt
- Zeilen ausgeben, in denen "Hier" am Anfang steht
Innerhalb einer Zeichenklasse in einer RE steht es für Verneinung.
sed -n '/F[^e]hler/p' < sed-test.txt
- Zeilen ausgeben, in denen das Wort "F.hler" vorkommt, wobei der 2. Buchstabe kein "e" sein darf
Möchte man dem Zeilenanfang eine Zeichenkette voranstellen genügt ein ^ als Suchmuster:
sed -n 's/^/Am Anfang stand /p' < sed-test.txt
- Jede Zeile beginnt mit 'Am Anfang stand '
Zeilen löschen
Löschen [d]
Der nachfolgende Aufruf löscht alle Zeilen ab der (einschließlich) 4. bis zum Dateiende:
sed '4,$d' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname
Das Entfernen aller Zeilen, die mit einem Leerzeichen beginnen, erledigt dieser Aufruf:
sed '/^ /d' test.txt
10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Der delete-Befehl ist die Umkehrung des print-Befehls: Die bei der Bereichsauswahl (mittels RE oder explizit) selektierten Zeilen werden "gelöscht", also nicht ausgegeben.
sed '/isst/d' < sed-test.txt
- Zeilen, die "isst" enthalten, werden nicht ausgegeben
sed '3d' < sed-test.txt
- die dritte Zeile wird nicht ausgegeben
Beispiele
Lösche die Nte Zeile
sed ‘Nd’ filename
- Check whether supplied command is true for this line, if true, deletes pattern space buffer and starts next cycle. i.e Read next line.
- If supplied command doesnt true, as its normal behaviour it prints the content of the pattern space buffer.
Delete Starting from 3rd line and every 2nd line from there.
Delete from 4th to 8th line from file.
Delete the last line from input.
Delete the line which matches the given pattern from input.
Deletes the line from which matches the given pattern to end of the file.
Deletes the line from which matches the given pattern and 2lines next to that.
Delete blank Line from a file using sed
Suchen und Ersetzen
In diesem Falle steht das Trennzeichen "/" an drei Stellen: vor und hinter der RE, also dem Suchmuster und hinter dem Ersetzungsmuster.
Der mittlere Schrägstrich ist also Ende-Delimiter für die RE und gleichzeitig Anfangs-Delimiter für den Ersetzungsstring.
Logischer Weise müsste der Schrägstrich viermal vorkommen, aber sed hat die beiden mittleren Schrägstriche zu einem verschmolzen.
Zeichen ersetzen [s]
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«:
sed 's#RegEx#Regulärer Ausdruck#' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname 4 5 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der 6 Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende 7 Mechanismen in Frage: 8 9 Keine Angabe Alle Zeilen 10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 Regulärer Ausdruck Zeilen, die den Regulären Ausdruck enthalten 14 1, Regulärer Ausdruck Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Globale Substitution
Wer genau hinschaut, 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:
sed -n 's#RegEx#Regulärer Ausdruck#gp' test.txt
13 Regulärer Ausdruck Zeilen, die den Regulären Ausdruck enthalten 14 1, Regulärer Ausdruck Von Zeile 1 bis zur ersten Zeile, die Regulärer Ausdruck enthält
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.
Speichern von Mustern und den späteren Zugriff darauf
Es soll die Numerierung der Zeilen von Einer- auf Zehnerschritte erhöht werden:
sed 's/^\([[:space:]]*[1-9]\{1,\}\)/\10/' test.txt
10 Der Aufruf des Stream Editors besitzt immer das Format: 20 30 sed 'Kommando' Dateiname 40 50 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der 60 Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende 70 Mechanismen in Frage: 80 90 Keine Angabe Alle Zeilen 100 Nummer Genau diese Zeile 110 Start, Ende Alle Zeilen von "Start" bis "Ende" 120 $ Symbolisiert die letzte Zeile 130 RegEx Zeilen, die den Regulären Ausdruck enthalten 140 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält* 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ß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.
Beispiel
"isst" soll in allen Zeilen durch "ist" ersetzt werden. Eigentlich müssten pro String ein Anfangs-/Ende-Delimiter verwendet werden.
/isst//ist/
- beide Strings müssten durch "/" begrenzt werden
- sed verschmilzt die mittleren Schrägstriche zu einem!
/isst/ist/
- # dies erscheint zunächst unlogisch.
Der Befehl "s" für "suchen & ersetzen" steht vor(!) der RE.
sed 's/isst/ist/' < sed-test.txt
- Befehl "s" steht am Anfang!
- sed selektiert alle Zeilen, in denen "isst" vorkommt, ersetzt "isst" durch "ist"
- und gibt das Ergebnis am Bildschirm aus
Um die Änderungen in die Datei zu schreiben, gibt es zwei Möglichkeiten:
mit Hilfe einer temporären Datei
sed 's/isst/ist/' < sed-test.txt > sed-test2.txt * Ausgabe in temporäre Datei umleiten
vim sed-test2.txt* Ergebnis kontrollieren!
mv sed-test2.txt sed-test.txt* Originaldatei ersetzen durch temporäre Datei
direkt
sed -i 's/isst/ist/' sed-test.txt* Vorsicht, Änderungen werden direkt in Datei geschrieben!
Im Beispiel würde sed in jeder Zeile nur das erste gefundene "isst" durch "ist" ersetzen. Um zu erreichen, dass alle Fundstellen geändert werden, muss ans Ende der Anweisung der g-Spezifizierer (=global) gesetzt werden:
sed 's/isst/ist/g' < sed-test.txt
Selektives Suchen und Ersetzen
Beim "normalen" Suchen und Ersetzen werden alle Zeilen in den Suchvorgang einbezogen. Es kommt jedoch vor, dass die Ersetzung nur innerhalb eines bestimmten Bereiches erfolgen soll. Die Bereichsauswahl kann, wie oben beschrieben, über eine RE oder explizit erfolgen.
Beispiel
Ans Ende aller Zeilen, in denen "isst" vorkommt, soll " --Fehler!" angehängt werden. Das normale Suchen und Ersetzen hilft hierbei nicht weiter, denn "isst" soll ja nicht ersetzt werden, sondern dient nur Selektion der Zeilen, an die das Suffix angehängt werden soll.
Es sind also zwei Vorgänge erforderlich:* Bereichsauswahl über die RE "/isst/"
- Suchen des Zeilenendes und ersetzen durch " --Fehler!".
Genau genommen wird nicht das Zeilenende ersetzt, sondern ein gedachte fiktives "leer-Zeichen" (sozusagen "") vor dem Zeilenende.
Damit sed weiß, dass sich Suchen und Ersetzen nur auf die Bereichsauswahl bezieht, steht es hinter der Bereichsauswahl in geschweiften Klammern. Sie können auch weggelassen werden. Ich rate jedoch dazu, sie zu verwenden, da die Logik des Befehls dadurch klarer wird.
sed '/isst/{s/$/ --Fehler!/}' < sed-test.txt
- /isst/ -> Bereichsauswahl über RE
- {...} -> Anweisung in "{...}" bezieht sich auf die vorangestellte Bereichsauswahl
- $ -> Platzhalterzeichen für "Zeilenende" (in Suchen & Ersetzen Anweisungen)
- s/$/ --Fehler!/ -> fiktives "leer-Zeichen" vor dem Zeilenende wird ersetzt durch " --Fehler!"
Bei expliziter Bereichsauswahl funktioniert dies analog.
Beispiel
Ans Ende der 2. und 3. Zeile soll " --Fehler!" gesetzt werden.
sed '2,3{s/$/ --Fehler!/}' < sed-test.txt
- 2,3 -> explizite Bereichsauswahl: Zeile 2-3
Beachten Sie, dass die explizite Bereichsauswahl durch keine Delimiterzeichen "/" eingegrenzt ist.
Beispiel
Ans Ende der letzten Zeile soll " --Ende" gesetzt werden.
sed '${s/$/ --Fehler!/}' < sed-test.txt
- # $ -> explizite Bereichsauswahl; "$" steht hier für "letzte Zeile"
Beispiel
an den Anfang der ersten Zeile soll "Anfang--" gesetzt werden.
sed '1{s/^/Anfang--/}' < sed-test.txt
- 1 -> explizite Bereichsauswahl
- ^ -> Platzhalterzeichen für "Zeilenanfang"
- ein fiktives "leer-Zeichen" ("") am Zeilenanfang wird ersetzt durch "Anfang--"
Der vorige Befehl funktioniert auch ohne {}, ist aber schwerer zu lesen:
sed '1s/^/Anfang--/' < sed-test.txt
Control-Character
Mit Hilfe von sed können verschiedenste Konvertierungen durchgeführt werden, z.B. von DOS- (CR-LF) zu Unix Dateiendezeichen (LF). Control-Character können entweder als escape-character oder als hexadezimal-character dargestellt werden.
Wichtige control-character
Bezeichnung escape hex "cat -A" linefeed \n \x0a $ carriage-return \r \x0d ^M tab \t \x09 ^I
Kontrollzeichen innerhalb von Variablen lassen sich auch sehr gut mit Hilfe des l-Befehls von sed am Bildschirm darstellen. Dies ist eine Alternative zu "cat -A"
a=$'Tabulator: \x09 CR: \x0d LF: \x0a' echo -e "$a" | sed -n 'l'
Escape-character
a="Zeile1\r\nZeile2"
am Ende von Zeile1 steht CR-LF (=DOS-Zeilenende)
echo -e "$a" | cat -A
Inhalt wird inkl. Kontrollzeichen ausgegeben und darstellbar gemacht (cat -A), der carriage-return wird als ^M dargestellt (0x0D)
echo -e "$a" | sed 's/\r//' | cat -A
der carriage-return wird durch "leer" ersetzt, ^M wird nicht mehr angezeigt
unset a
Hexadezimal-character
a=$'Zeile1\x0d\x0aZeile2'
am Ende von Zeile1 steht CR-LF (0x0d+0x0a)
echo -e "$a" | cat -A
echo -e "$a" | sed 's/\x0d//' | cat -A unset a
Beispiele
Text in Dateien mit RegEx
- s is substitute command
- / is a delimiter
- REGEXP is regular expression to match
- REPLACEMENT is a value to replace
- n Could be any number,replace nth instance of the REGEXP with REPLACEMENT.
- p If substitution was made, then prints the new pattern space.
- i match REGEXP in a case-insensitive manner.
- w file If substitution was made, write out the result to the given file.
- We can use different delimiters ( one of @ % ; : ) instead of /
Ersetzen von “Linux” durch “Unix” (s)
Alle Treffer ersetzen (s//g)
Jeden zweiten Treffer ersetzen (s//2)
Nur ersetzen, wenn eine Zeile einen Treffer ergibt
Letzten X Zeichen jeder Zeile löschen
Kommentare löschen
sed -e 's/#.*//' thegeekstuff.txt
Kommentare und leere Zeilen löschen
sed -e 's/#.*//;/^$/d' thegeekstuff.txt
Zeilenwechsel konvertieren
DOS newlines (CR/LF) ins Unix-Format ändern
$sed 's/.$//' filename
Rekursives Suchen und Ersetzen
Ersetzen einer Zeichenkette in allen Daten einer Verzeichnisstruktur.
find . -type f -print0 | xargs -0 -n 1 sed -i -e "s/suche/ersetze/g"
Beispiel mit escape Zeichen \
‘typo3temp/pics ersetzen mit ‘../../typo3temp/pics
find . -name *.html -type f -print0 | xargs -0 -n 1 sed -i -e \ "s/’temp\/pics/’..\/..\/temp\/pics/g"
HTML Tags aus Datei entfernen
In this example, the regular expression given in the sed command matches the html tags and replaces with the empty.
sed -e 's/<[^>]*>//g' This is an example. This is an example.
Mehrere Kommandos [-e]
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:
sed -e '3,$d' -e 's# #.#g' test.txt
.1 Der.Aufruf.des.Stream.Editors.besitzt.immer.das.Format: .2 * Zuerst werden alle Zeilen ab der 3. Zeile entfernt
- anschließend die Leerzeichen durch Punkte ersetzt
Die Reihenfolge der Kommandos kann das Ergebnis beeinflussen
Eine alternative Angabe ist die Gruppierung mehrerer Kommandos.
Hierzu werden diese in geschweifte Klammern gesetzt und ein Semikolon nach jedem Kommando eingefügt
sed '{s/ /./g;3,$d}' test.txt
.1 Der.Aufruf.des.Stream.Editors.besitzt.immer.das.Format: .2
Verkettung von sed-Anweisungen
sed-Anweisungen lassen sich entweder mit Hilfe der Option "-e" aneinanderreihen oder mittels Pipe.
Die Aneinanderreihung mittels Pipe macht dann Sinn, wenn die Auswahlmenge schrittweise reduziert werden soll, analog zum Aneinanderpipen von grep-Kommandos.
Beispiel
In der Datei httpd.conf sollen nur die Zeilen ausgegeben werden, die nicht mit "#" beginnen. Sodann soll "Allow" durch "Deny" ersetzt werden. Zunächst werden Zeilen selektiert, die nicht mit "#" beginnen. Die Ausgabe wird sodann mittels Pipe an einen weiteren sed-Prozess zu übergeben, der die Wortersetzung durchführt.
cat httpd.conf | sed -n '/^[^#]/p' | sed 's/Allow/Deny/'
- Reduktion der Auswahlmenge
- Ersetzung
Eine andere Möglichkeit besteht darin, mehrere Anweisungen an sed zu übergeben, die sukzessive abgearbeitet werden. Dies kann z.B. dann verwendet werden, wenn innerhalb einer Datei mehrere "Suchen & Ersetzen"-Befehle nacheinander durchgeführt werden sollen.
Nach jedem s-Befehl werden sämtliche Zeilen ausgegeben, sodass beim folgenden s-Befehl wieder die gesamte Datei zur Verfügung steht.
Beispiel
in der Datei httpd.conf soll "Allow" durch "Deny" ersetzt werden und "localhost" durch "myserver"
cat httpd.conf | sed -e 's/Allow/Deny/g' -e 's/localhost/myserver/g'
- Ersetzung1
- Ersetzung2
Statt mehrere Anweisung mittels "-e" aneinanderzureihen, kann man diese auch durch ";" verketten, wobei das einfache Hochkomma nur am Anfang und am Ende stehen darf.
Die Option "-e" kann hierbei weggelassen werden.
cat httpd.conf | sed 's/Allow/Deny/g; s/localhost/myserver/g'
- analog zur vorigen Anweisung
Einfügen [i|a]
Der einzufügende Text muss auf einer neuen Zeile stehen, wobei jede Zeile bis auf die letzte durch einen Backslash abzuschließen ist. * »i« (insert) fügt den Text vor der betreffenden Zeile ein
- »a« (append) schreibt den neuen Text nach der Zeile.
Beispiel
sed '8i\
===========================================\ Angabe Bereich von Zeilen\ ===========================================' test.txt 1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname 4 5 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der 6 Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende 7 Mechanismen in Frage: =========================================== Angabe Bereich von Zeilen =========================================== 8 9 Keine Angabe Alle Zeilen 10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Einfügen aus einer Datei [r]
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 Methode ist, den einzusetzenden Text in einer separaten Datei zu erfassen und Sed jene unterzuschieben.
cat ins.txt
=========================================== Angabe Bereich von Zeilen =========================================== Dieser Text lässt sich mittels des r-Kommandos einfach an beliebiger Stelle einordnen:
sed '8r ins.txt' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname 4 5 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der 6 Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende 7 Mechanismen in Frage: 8 =========================================== Angabe Bereich von Zeilen =========================================== 9 Keine Angabe Alle Zeilen 10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Schreiben in eine Datei [w]
Das Ergebnis des Stream Editors lässt sich in einer Datei speichern:
sed -n '/^1/w out.txt' test.txt cat out.txt
10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält
Änderungen in Datei schreiben und auf Konsole (s//gpw)
The example below has substitution with three flags. It substitutes all the occurance of Linux to Linux-Unix and prints the substituted output as well as written the same to the given the file.
sed -n 's/Linux/Linux-Unix/gpw output' thegeekstuff.txt 1. Linux-Unix Sysadmin, Linux-Unix Scripting etc. 4. Storage in Linux-Unix
cat output 1. Linux-Unix Sysadmin, Linux-Unix Scripting etc. 4. Storage in Linux-Unix
Dateien direkt bearbeiten
Häufig ist es sinnvoll Dateien direkt zu bearbeiten, anstatt sie auf die Standardausgabe zu schreiben.
Dies ist mit der Option »-i« möglich.
Der folgende Befehl ersetzt alle "Hallo" in der Datei test.txt durch "Hey", ohne eine Ausgabe zu erzeugen.
sed -i"" 's|Hallo|Hey|g' test.txt
Achtung! Das "" nach -i ist notwendig.
Mit dieser Option ist es auch sehr einfach möglich mehrere Dateien zu bearbeiten.
Hiermit werden alle Dateien im aktuellen Ordner die mit .txt enden wie gerade beschrieben bearbeitet:
sed -i"" 's|Hallo|Hey|g' *.txt
Dateien ergänzen
Zeile am Dateianfang einfügen
Dies ist auch ohne sed möglich, z.B. mit Hilfe von echo und cat
cat - <<< "Anfang" sed-test.txt > sed-test2.txt echo "Anfang" | cat - sed-test.txt > sed-test2.txt echo "Anfang" > sed-test2.txt; cat sed-test.txt >> sed-test2.txt
Mit Hilfe von sed geht dies eleganter.
sed '1iAnfang' < sed-test.txt > sed-test2.txt
- 1=Zeile 1 (explizite Bereichsauswahl)
- i=insert-Befehl
Zeile innerhalb des Textes einfügen
Die folgende Anweisung fügt eine neue Zeile vor der vorletzten Zeile ein.
sed '/vorletzte/idies ist die vorvorletzte Zeile' < sed-test.txt > sed-test2.txt
- /vorletzte/ = Bereichsauswahl über RE
- i=insert-Befehl
Zeile ans Dateiende anhängen
sed '$aEnde' < sed-test.txt > sed-test2.txt
- $=letzte Zeile (explizite Bereichsauswahl)
- a=append-Befehl
Zeichen am Zeilenanfang einfügen
Das Zeichen "#" soll in allen Zeilen an den Zeilenanfang gesetzt werden.
sed 's/^/#/' < sed-test.txt
- s =suchen & ersetzen
- /^/ ="Zeilenanfangszeichen"
- /#/ = Replace-String
Die Anweisung erscheint auf den ersten Blick nicht ganz logisch. Sie ist folgendermaßen zu interpretieren: Ersetze in jeder Zeile das am Zeilenanfang gedachte fiktive "leer-Zeichen" (sozusagen "") durch das #-Zeichen.
Es wird also nicht der Zeilenanfang selbst ersetzt, was ja gar nicht möglich wäre, da es kein Zeilenanfangszeichen analog zum Zeilenendezeichen gibt. Einfacher verständlich wird die Anweisung, wenn man ein bestimmtes Wort am Zeilenanfang ersetzen lässt:
sed 's/^Hier/Dort/' < sed-test.txt
- Hier" am Zeilenanfang wird ersetzt durch "Dort"
Beispiel
Das Zeichen "#" soll bei Zeilen, die mit "Hier" beginnen an den Zeilenanfang gesetzt werden.
sed 's/^Hier/#Hier/' < sed-test.txt
Beispiel
Das Zeichen "#" soll in Zeilen, in denen "letzt" vorkommt, an den Zeilenanfang gesetzt werden. Dieser Fall unterscheidet sich von den vorigen, weil das "suchen & ersetzen" auf einen bestimmten Bereich beschränkt werden muss. Hierzu werden geschweifte Klammern verwendet.
sed '/letzt/{s/^/#/}' < sed-test.txt
- /letzt/ =RE; Zeilen, in denen "letzt" vorkommt, werden selektiert
- {s...} = "suchen & ersetzen" wird nur in den selektierten Zeilen ausgeführt
Nächste Zeile beabeiten[n]
Soll erst die dem Suchmuster folgende Zeile manipuliert werden, ist das n-Kommando der beste Kandidat:
sed -n '8,${n;s/\(.\{1,\}\)/*\1/p;}' test.txt
* 9 Keine Angabe Alle Zeilen *11 $ Symbolisiert die letzte Zeile *13 RegEx Zeilen, die den Regulären Ausdruck enthalten
Die Kommandozeile ist schwer verdaulich... aber der Reihe nach:
»-n« | als Kommandozeilenoption besagt, dass die 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, dass die nächste Zeile bearbeitet 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 mit »\(...\)« 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. |
Zeichen tauschen [y]
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 'y/abcdefghijklmnopqrstuvwxyz/zyxwvutsrqponmlkjihgfedcba/' test.txt
1 Dvi Afuifu wvh Sgivzn Ewrglih yvhrgag rnnvi wzh Flinzg: 2 3 hvw 'Klnnzmwl' Dzgvrmznv 4 5 Dzyvr pzmm wvn Klnnzmwl nrgtvgvrog dviwvm, dvoxsv Zvrovm wvi 6 Ermtzyvwzgvr vh yvziyvrgvm hloo. Aoh Awivhhrvifmt plnnvm ulotvmwv 7 Mvxszmrhnvm rm Fiztv: 8 9 Kvrmv Amtzyv Aoov Zvrovm 10 Nfnnvi Gvmzf wrvhv Zvrov 11 Sgzig, Emwv Aoov Zvrovm elm "Sgzig" yrh "Emwv" 12 $ Sbnylorhrvig wrv ovgagv Zvrov 13 RvtEc Zvrovm, wrv wvm Rvtfo/auml;ivm Afhwifxp vmgszogvm 14 1, RvtEc Vlm Zvrov 1 yrh afi vihgvm Zvrov, wrv RvtEc vmgsäog
Sed vorzeitig beenden [q]
Manchmal ist es sinnvoll, den Stream Editor vorzeitig zu beenden:
sed '3q' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname
sed -n '/sed/{p;q;}' test.txt
3 sed 'Kommando' Dateiname
Zeilentausch [h|g|G|x ]
Die aktuell bearbeitete Zeile hält der Sed in einem Zwischenspeicher und bearbeitet sie 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.
h | Mit dem Kommando »h« kann der aktuelle Zwischenspeicher in einen Puffer gesichert werden (»holding buffer«). |
---|---|
G | Das Kommando »G« fügt den Inhalt dieses Sicherungspuffers hinter der aktuell bearbeiteten Zeile ein. |
g | »g« ersetzt die aktuelle Zeile durch den Inhalt des Sicherungspuffers. |
x | Den Inhalt der beiden Puffer vertauscht das Kommando »x«. |
Beispiel 1
sed -e '/sed/{h;d;}' -e '4G' -e '4q' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 4 3 sed 'Kommando' Dateiname
sed -e '/sed/{h;d;}' -e '4g' -e '5q' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname 5 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der
Erklärung
- Das erste Kommando »-e '/sed/{h;d;}'« in 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 '4g'« ersetzt die 4.Zeile.
- Das letzte Kommando »-e '4q'« beendet die Arbeit des Editors nach der 4. Zeile.
Beispiel 2
sed -e '/Aufruf/h' -e '/Angabe/x' -e '$G' test.txt
1 Der Aufruf des Stream Editors besitzt immer das Format: 2 3 sed 'Kommando' Dateiname 4 5 Dabei kann dem Kommando mitgeteilt werden, welche Zeilen der 6 Eingabedatei es bearbeiten soll. Als Adressierung kommen folgende 7 Mechanismen in Frage: 8 1 Der Aufruf des Stream Editors besitzt immer das Format: 10 Nummer Genau diese Zeile 11 Start, Ende Alle Zeilen von "Start" bis "Ende" 12 $ Symbolisiert die letzte Zeile 13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält 9 Keine Angabe Alle Zeilen
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.
Quellen
- Linuxfibel (de.linwiki.org/wiki/Linuxfibel_-_Unix-Werkzeuge_-_Sed)
- Dokumentation zu GNU sed (www.gnu.org/software/sed/manual/sed.html)
- The Geek Stuff (http://www.thegeekstuff.com/)
Sed-Skripte
Kompliziertere und häufig benötigte Sed-Aufrufe schreibt man besser in eine Datei. Der Aufruf von Sed sieht dann wie folgt aus:
sed -f <Skript_Datei> <zu_bearbeitende_Datei>
Beim Schreiben eines Skripts gelten folgende Regeln: * Beginnt eine Zeile mit einem Doppelkreuz #, so handelt es sich um einen Kommentar
- Vor und nach einem Kommando dürfen keine Leerzeichen, Tabulatoren... stehen
- Mehrere Kommandos auf einer Zeile, sind sie durch Semikola voneinander zu trennen
Der Stream Editor wird das gesamte Skript auf jede Zeile der Eingabedatei anwenden.
Als Beispiel dient ein Skript, dass alle deutschen Umlaute in der Eingabedatei umschreibt.
cat umlaut
## Ersetzen Umlaute s/ä/\ae/g s/ü/\ue/g s/ö/\oe/g s/Ä/\ae/g s/Ü/\Ue/g s/Ö/\Oe/g s/ß/\ss/g
Das Anwendungsbeispiel demonstriert die Möglichkeit der Kopplung von Kommandozeilenbefehlen und einem Skript:
sed -e '1,12d' -f umlaut test.txt
13 RegEx Zeilen, die den Regulären Ausdruck enthalten 14 1, RegEx Von Zeile 1 bis zur ersten Zeile, die RegEx enthält