sed: Unterschied zwischen den Versionen

Aus Mikiwiki
Zur Navigation springen Zur Suche springen
 
(26 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 7: Zeile 7:
Normalerweise erhält sed die zu verarbeitenden Texte über die Standardeingabe (stdin). Dabei können eine oder mehrere Dateien angegeben werden. Damit die Shell den Befehl nicht auswertet, wird er in einfache Hochkommas gesetzt.
Normalerweise erhält sed die zu verarbeitenden Texte über die Standardeingabe (stdin). Dabei können eine oder mehrere Dateien angegeben werden. Damit die Shell den Befehl nicht auswertet, wird er in einfache Hochkommas gesetzt.


sed [Optionen] 'Befehle' Dateien
<pre class=wiki>
sed [Optionen] 'Befehle' Dateien
</pre>


Die Angabe, welche Zeilen oder Dateibereiche zu bearbeiten sind, wird als "Adresse" bezeichnet.
Die Angabe, welche Zeilen oder Dateibereiche zu bearbeiten sind, wird als "Adresse" bezeichnet.
Zeile 13: Zeile 15:
Die Befehle können auch in eine Skriptdatei geschrieben werden.
Die Befehle können auch in eine Skriptdatei geschrieben werden.


sed -f scriptfile sourcefile > targetfile
<pre class=wiki>
sed -f scriptfile sourcefile > targetfile
</pre>
 
== Zu fluchtende Zeichen ==
 
sed verwendet grundlegende reguläre Ausdrücke - um die Zeichen <code>$ . * [ \ ^</code> als gewöhnliche Zeichen zu behandeln, müssen diese mit dem rückwärtsgerichteten Schrägstrich gefluchtet werden. Buchstaben, Zahlen und die Zeichen <code>( ) { } + ? |</code> müssen nicht gefluchtet werden.
 
In Wirklichkeit ist das alles aber viel komplizierter... siehe
* https://unix.stackexchange.com/questions/32907/what-characters-do-i-need-to-escape-when-using-sed-in-a-sh-script


== Optionen ==
== Optionen ==
Zeile 38: Zeile 49:


{| class=wikitable width=100%
{| class=wikitable width=100%
! width=15% | Beispiel !! Beschreibung
! width=20% | Beispiel !! Beschreibung
|-
|-
| <tt>s/CA/California/g</tt> || ändert alle "CA" der Quelldatei in "California". Da keine Adresse angegeben ist, werden alle Zeilen bearbeitet.
| <tt>s/CA/California/g</tt> || ändert alle "CA" der Quelldatei in "California". Da keine Adresse angegeben ist, werden alle Zeilen bearbeitet.
Zeile 61: Zeile 72:
Ausgabe des Inhalts der Datei "file".
Ausgabe des Inhalts der Datei "file".


  $ <b>sed '' file</b>
  $ <b><nowiki>sed '' file</nowiki></b>


Ausgabe des Inhalts der Datei "file", wobei die dritte Zeile zweimal angezeigt wird.
Ausgabe des Inhalts der Datei "file", wobei die dritte Zeile zweimal angezeigt wird.
Zeile 116: Zeile 127:


  $ <b><nowiki>sed 's#http://abc.org/#http://xyz.org/#g' file</nowiki></b>
  $ <b><nowiki>sed 's#http://abc.org/#http://xyz.org/#g' file</nowiki></b>
Ersetzen von Zeilenumbrücken ("\n") in der Datei "file" durch die Zeichenfolge "ABCD".
$ <b>sed ':M;N;$!bM;s#\n#ABCD#g' file</b>
Ersetzen des Zeichens "`" in der Datei "file" durch "'" (Apostroph).
$ <b><nowiki>sed 's/`/'\''/g' file</nowiki></b>
Umwandlung des ersten Buchstabens jeder Zeile der Datei "file" in einen Grossbuchstaben.
$ <b>sed 's/^\(\<.\)/\U\1/g' file</b>
Umwandlung des ersten Buchstabens jeder Zeile der Datei "file" in einen Kleinbuchstaben.
$ <b>sed 's/^\(\<.\)/\L\1/g' file</b>
Umwandlung des ersten Buchstabens nach der ersten vorkommenden Klammer "(" jeder Zeile in einen Grossbuchstaben.
$ <b>echo "abc(Zuz)hjh" | sed 's/(\(.\)/(\U\1/'</b>
abc(Zuz)hjh
Entfernen eckiger Klammern.
* https://serverfault.com/questions/466118/using-sed-to-remove-both-an-opening-and-closing-square-bracket-around-a-string/828633
$ <b>echo "[Text]" | sed 's/\(\[\|\]\)//g'</b>
Text
Entfernen der Zeichenfolgen "EAN: " oder "UPC: " am Zeilenbeginn.
$ <b>echo "EAN: 9789953897035" | sed -e '${s/^EAN: \|^UPC: //}'</b>
9789953897035


=== Mehrere Befehle ===
=== Mehrere Befehle ===


Löschen von Zeile 5 und aller folgenden bis zum Dateiende der Datei "file". Im Rest der Datei wird die Zeichenfolge "KDE" durch "Gnome" ersetzt. Für diesen Vorgang gibt es zwei Möglichkeiten.
Löschen von Zeile 5 und aller folgenden bis zum Dateiende der Datei "file". Im Rest der Datei wird die Zeichenfolge "KDE" durch "Gnome" ersetzt.


  $ <b>sed -e '5,$d -e 's/KDE/Gnome/g' file</b>
  $ <b>sed -e '5,$d' -e 's/KDE/Gnome/g' file</b>
oder
  $ <b>sed '{5,$d;'s/KDE/Gnome/g' file</b>
  $ <b>sed '{5,$d;'s/KDE/Gnome/g' file</b>


=== Lesen und Schreiben ===
=== Lesen und Schreiben ===


Einfügen der Datei "infile" nach der dritten Zeile der DAtei "file".
Einfügen der Datei "infile" nach der dritten Zeile der Datei "file".


  $ <b>sed '3r infile' file</b>
  $ <b>sed '3r infile' file</b>
Zeile 163: Zeile 207:


  $ <b>sed -i .bak -f scriptfile file</b>
  $ <b>sed -i .bak -f scriptfile file</b>
Einfügen der Zeichenfolge "abc" samt Zeilenumbruch (LF) ganz an den Anfang der Datei "datei.txt", sodass diese als erste Zeile erscheint.
$ <b>sed -i '1s/^/abc\n/' datei.txt</b>


=== Kombination mit anderen Programmen ===
=== Kombination mit anderen Programmen ===
Zeile 217: Zeile 265:
Ersetzen der IP-Adresse "10.0.1.1" in allen Dateien im Verzeichnis "/etc" (z. B. wenn gerade eine Maschine geklont wurde) durch die Adresse "10.0.5.5".
Ersetzen der IP-Adresse "10.0.1.1" in allen Dateien im Verzeichnis "/etc" (z. B. wenn gerade eine Maschine geklont wurde) durch die Adresse "10.0.5.5".


  $ <b>for i in $(grep -rlIs "10.0.1.1" /etc); do echo "changing file $i"; sed 's/10.0.1.1/10.0.5.5/' $i > sed.tmp; mv sed.tmp $i; done</b>
  $ <b>for i in $(grep -rlIs "10.0.1.1" /etc); do echo "changing file $i"; \
    sed 's/10.0.1.1/10.0.5.5/' $i > sed.tmp; mv sed.tmp $i; done</b>


Einfügen einer Zeile über einem bestimmten Suchmuster.
Einfügen einer Zeile über einem bestimmten Suchmuster.


  $ <b>echo "Das ist ein Text\nmit einem SUCHMUSTER" | sed -e '/SUCHMUSTER/{;i\' -e 'der auch in einer Datei stehen könnte' -e '}'</b>
  $ <b>echo "Das ist ein Text\nmit einem SUCHMUSTER" | \
    sed -e '/SUCHMUSTER/{;i\' -e 'der auch in einer Datei stehen könnte' -e '}'</b>
  der auch in einer Datei stehen könnte
  der auch in einer Datei stehen könnte
  Das ist ein Text\nmit einem SUCHMUSTER
  Das ist ein Text\nmit einem SUCHMUSTER
Zeile 250: Zeile 300:
== Weblinks ==
== Weblinks ==


* [http://sed.sourceforge.net/ sed.sourceforge.net] - tonnenweise langweilige manpages
{{Weblinks}}
{{dewi|Sed_(Unix)|Sed (Unix)}}
{{url|US|Sourceforge|eng|http://sed.sourceforge.net/|The SED $HOME}}
* [http://www.dbnet.ece.ntua.gr/~george/sed/OLD/sedfaq.html The sed FAQ]
{{url_dewikipedia|Sed_(Unix)|Sed (Unix)}}
* [http://www.student.northpark.edu/pemente/sed/sed1line.txt Handy oneliners for sed] (Eric Pement)
{{url|GR||eng|http://www.dbnet.ece.ntua.gr/~george/sed/OLD/sedfaq.html|The sed FAQ}}
* [http://stefan.waidele.info/sed-einzeiler-deutsche-ubersetzung/ sed-Einzeiler : deutsche Übersetzung] (Stefan.Waidele.info)
{{url|US|Eric Pement|eng|http://www.student.northpark.edu/pemente/sed/sed1line.txt|Handy oneliners for sed}}
{{url|DE|Stefan Waidele|ger|http://stefan.waidele.info/sed-einzeiler-deutsche-ubersetzung/|sed-Einzeiler : deutsche Übersetzung|icon=http://stefan.waidele.info/wp-content/themes/starscape/styles/favicons/starscape.ico}}
{{url|DE|Vimperl|ger|http://www.vimperl.de/linux/sed.html|Sed|Einige Tips}}
{{Fuss}}
 
* https://phoenixnap.com/kb/sed-delete-line




{{cat|Shell-Befehll}}
{{cat|Shell-Befehl}}
{{cat|Texteditor}}
{{cat|Texteditor}}
{{cat|Textverarbeitung}}

Aktuelle Version vom 14. November 2024, 09:50 Uhr

Der Shell-Befehl sed (stream editor) ist ein Zeileneditor und arbeitet im Gegensatz zu Texteditoren wie vi nicht interaktiv. Stattdessen wird vorher auf der Befehlszeile bestimmt, welche Textbereiche zu löschen, zu ändern oder einzufügen sind. sed bearbeitet jede Zeile mit den angeführten Befehlen und schreibt sie in einen Puffer, dessen Inhalt zuletzt - falls nicht anders definiert - auf der Standardausgabe (stdout) erscheint.

Der Befehl N liest eine weitere Zeile in den "pattern space", ohne die aktuelle Zeile zu entfernen. Andere Befehle beenden sed, bevor die ganze Quelldatei bearbeitet wurde. Zudem gibt es neben dem "pattern space" auch den "hold space".

Syntax

Normalerweise erhält sed die zu verarbeitenden Texte über die Standardeingabe (stdin). Dabei können eine oder mehrere Dateien angegeben werden. Damit die Shell den Befehl nicht auswertet, wird er in einfache Hochkommas gesetzt.

sed [Optionen] 'Befehle' Dateien

Die Angabe, welche Zeilen oder Dateibereiche zu bearbeiten sind, wird als "Adresse" bezeichnet.

Die Befehle können auch in eine Skriptdatei geschrieben werden.

sed -f scriptfile sourcefile > targetfile

Zu fluchtende Zeichen

sed verwendet grundlegende reguläre Ausdrücke - um die Zeichen $ . * [ \ ^ als gewöhnliche Zeichen zu behandeln, müssen diese mit dem rückwärtsgerichteten Schrägstrich gefluchtet werden. Buchstaben, Zahlen und die Zeichen ( ) { } + ? | müssen nicht gefluchtet werden.

In Wirklichkeit ist das alles aber viel komplizierter... siehe

Optionen

Option Beschreibung
p Ausgabe der entsprechenden Zeilen auf den Bildschirm.
d Löschen des angegebenen Bereichs.
s Ersetzung der angegebenen Zeichenkette.
a Einfügen von Text hinter den adressierten Zeilen (beim Einsatz in Skripten).
i Einfügen von Text vor den adressierten Zeilen (beim Einsatz in Skripten).
c Ersetzen von Zeilen oder Zeilenbereichen (beim Einsatz in Skripten).
r Lesen des Inhalts einer Datei und Setzen des Inhalts hinter die entsprechende Adresse.
w Schreiben der adressierten Zeilen oder Bereiche in eine neue Datei.
Beispiel Beschreibung
s/CA/California/g ändert alle "CA" der Quelldatei in "California". Da keine Adresse angegeben ist, werden alle Zeilen bearbeitet.
s/&#141;&#141;*/&#141;/g ersetzt einen oder mehrere Leerschläge hintereinander durch einen einzelnen Leerschlag.
/Sebastopol/s/CA/California/g ändert alle "CA" der Quelldatei in "California", falls die jeweilige Zeile "Sebastopol" enthält. Da hier eine Adresse vorhanden ist (Sebastopol), werden nur die der Adresse entsprechenden Zeilen bearbeitet.
d löscht alle Zeilen
  • 1d löscht die erste Zeile
  • $d löscht die letzte Zeile
  • /^$/d löscht leere Zeilen
  • /^\.TS/,/^\.TE/d löscht alle Zeilen, auf die das erste Muster passt bis und mit der ersten Zeile, auf die das zweite Muster passt
/^\.TS/,/^\.TE/d{
/^$/d
}
löscht leere Zeilen nur in dem von den beiden Mustern vorgegebenen Bereich. Zwischen den geschweiften Klammern (die je auf eigenen Zeilen wie im Beispiel stehen müssen) können auch mehrere Befehle vorkommen.

Verwendung

Option "p"

Ausgabe des Inhalts der Datei "file".

$ sed '' file

Ausgabe des Inhalts der Datei "file", wobei die dritte Zeile zweimal angezeigt wird.

$ sed '3p' file

Ausgabe nur der dritten Zeile der Datei "file".

$ sed -n '3p' file

Option "d"

Löschen der ersten Zeile der Datei "file".

$ sed '1d' file

Löschen der zweiten bis vierten Zeile der Datei "file".

$ sed '2,4d' file

Löschen jeder dritten Zeile (ausgehend von der ersten) der Datei "file".

$ sed '1~3d' file

Löschen von Zeile 5 und aller folgenden bis zum Dateiende der Datei "file".

$ sed '5,$d' file

Löschen aller Zeilen, die mit einem Rautenzeichen beginnen (z. B. zum besseren Betrachten von Konfigurationsdateien). Dabei werden allerdings auch die Leerzeilen mit ausgegeben.

$ sed '/^#/d' /etc/hosts

Ausgabe aller Zeilen, die mit einem Zeichen beginnen das kein Rautenzeichen ist. Leerzeilen werden also nicht ausgegeben.

$ sed -n '/^ [^#].*/p' /etc/hosts

Option "s"

Mit der Option "s" werden Zeichenketten ersetzt. Nach dem Befehl folgt ein Trennzeichen, das Suchmuster, ein weiteres Trennzeichen, die neu einzufügende Zeichenkette und ein abschliessendes Trennzeichen. Als Trennzeichen kann ein beliebiges Zeichen verwendet werden, es darf aber nicht im Suchmuster vorkommen.

Ersetzen der jeweils ersten Zeichenfolge "abc" durch "xyz" in jeder Zeile der Datei "file".

$ sed 's/abc/xyz/' file

Ersetzen aller Zeichenfolgen "abc" durch "xyz" in jeder Zeile der Datei "file".

$ sed 's/abc/xyz/g' file

Ersetzen aller Zeichenfolgen "abc" durch "xyz" in Zeile 3 der Datei "file".

$ sed '3s/abc/xyz/g' file

Ersetzen aller Zeichenfolgen "http://abc.org/" durch "http://xyz.org/" in jeder Zeile der Datei "file". Da der Schrägstrich hier im Suchmuster vorkommt, wird als Trenner das Rautenzeichen verwendet.

$ sed 's#http://abc.org/#http://xyz.org/#g' file

Ersetzen von Zeilenumbrücken ("\n") in der Datei "file" durch die Zeichenfolge "ABCD".

$ sed ':M;N;$!bM;s#\n#ABCD#g' file

Ersetzen des Zeichens "`" in der Datei "file" durch "'" (Apostroph).

$ sed 's/`/'\''/g' file

Umwandlung des ersten Buchstabens jeder Zeile der Datei "file" in einen Grossbuchstaben.

$ sed 's/^\(\<.\)/\U\1/g' file

Umwandlung des ersten Buchstabens jeder Zeile der Datei "file" in einen Kleinbuchstaben.

$ sed 's/^\(\<.\)/\L\1/g' file

Umwandlung des ersten Buchstabens nach der ersten vorkommenden Klammer "(" jeder Zeile in einen Grossbuchstaben.

$ echo "abc(Zuz)hjh" | sed 's/(\(.\)/(\U\1/'
abc(Zuz)hjh

Entfernen eckiger Klammern.

$ echo "[Text]" | sed 's/\(\[\|\]\)//g'
Text

Entfernen der Zeichenfolgen "EAN: " oder "UPC: " am Zeilenbeginn.

$ echo "EAN: 9789953897035" | sed -e '${s/^EAN: \|^UPC: //}'
9789953897035

Mehrere Befehle

Löschen von Zeile 5 und aller folgenden bis zum Dateiende der Datei "file". Im Rest der Datei wird die Zeichenfolge "KDE" durch "Gnome" ersetzt.

$ sed -e '5,$d' -e 's/KDE/Gnome/g' file
oder
$ sed '{5,$d;'s/KDE/Gnome/g' file

Lesen und Schreiben

Einfügen der Datei "infile" nach der dritten Zeile der Datei "file".

$ sed '3r infile' file

Schreiben der Zeilen 25 bis 35 der Datei "file" in die neue Datei "outfile".

$ sed '25,35w outfile' file

sed-Skript

Mehrere sed-Befehle können auch in eine Skript-Datei geschrieben werden, die dann mit der Option "-f" auf die gewünschten Dateien angesetzt wird.

Löschen von Zeile 2 und Ergänzen des Texts "Nach der dritten Zeile" nach Zeile 3 der Datei "file". Für den Befehl "a" ist es wichtig, dass nach dem Befehl ("3a") ein umgekehrter Schrägstrich und Zeilenumbruch eingefügt wird. Der einzufügende Text steht dann in einer neuen Zeile. Handelt es sich um mehrere Zeilen, so muss jede (bis auf die letzte) mit einem umgekehrten Schrägstrich abgeschlossen werden.

$ more scriptfile
2d
3a\
Nach der dritten Zeile.\
Noch etwas.\
Und Schluss.
$ sed -f scriptfile file

Schreiben in eine Datei

sed verändert standardmässig nicht die Originaldatei, sondern schreibt seine Ausgabe auf die Standardausgabe (stdout).

Schreiben der Ausgabe in die Datei "outfile".

$ sed -f scriptfile file > outfile

Schreiben der Ausgabe direkt in die Originaldatei "file".

$ sed -i -f scriptfile file

Schreiben der Ausgabe direkt in die Originaldatei "file", wobei die Originaldatei unter dem Namen "file.bak" erhalten bleibt.

$ sed -i .bak -f scriptfile file

Einfügen der Zeichenfolge "abc" samt Zeilenumbruch (LF) ganz an den Anfang der Datei "datei.txt", sodass diese als erste Zeile erscheint.

$ sed -i '1s/^/abc\n/' datei.txt

Kombination mit anderen Programmen

Angenommen in einem Verzeichnis liegen mehrere Dateien mit Leerzeichen und Bindestrichen im Namen, die man durch Unterstriche ersetzen möchte. Ein solches Skript sollte erst getestet werden. Wenn alles in Ordnung ist, können die Dateien mit dem Befehl mv umbenannt werden.

$ ls -1 *.txt
test 1-0.txt
test 2-5.txt
$ ls -1 *.txt | sed 's/[ -]/_/'
test_1-0.txt
test_2-5.txt
$ for i in *.txt; do mv -v "$i" $(echo $i | sed 's/[ -]/_/'); done
,,test 1-0.txt" -> ,,test_1-0.txt"
,,test 2-5.txt" -> ,,test_2-5.txt"

Zählen aller Worte der Datei "file", in denen doppelte Buchstaben enthalten sind. "(.\)" ist dabei der Zwischenpuffer, "\1" die Puffer-Referenzierung.

$ sed -n '/\(.\)\1/p' file | wc -l

Ersetzen des ersten Zeichens ":" der Datei "file" durch einen Leerschlag.

$ sed 's/:/ /' file

Ersetzen aller Zeichen ":" der Datei "file" durch je einen Leerschlag.

$ sed 's/:/ /g' file

Ersetzen aller Zeichen ":" der Datei "file" durch die Zeichenfolge Leerschlag Doppelpunkt Leerschlag (" : "). Das Zeichen ":" wird dabei in einen Zwischenspeicher geladen und mit "\1" referenziert.

$ sed 's/\(:\)/ \1 /g' file

Ersetzen des Trennzeichens ":" in der Datei "/etc/passwd" durch ein Leerzeichen und Ausgabe auf den Bildschirm. Dafür gibt es zwei Möglichkeiten.

$ sed -e "s,:, ,g" /etc/passwd
$ cat /etc/passwd | sed -e "s,:, ,g"

Ausgabe der ersten fünf Zeilen der Datei "file.txt".

$ sed '5q' file.txt

Ausgabe der Datei "file.txt" ab Zeile 5 bis zum Dateiende.

$ sed -n '5,$p' file.txt

Ausgabe der Zeilen 10 bis und mit 20 der Datei "file.txt".

$ sed -n '10,20p' file.txt

Ausgabe der Datei "file.txt", wobei die vierte und fünfte Zeile gelöscht werden.

$ sed '4,5d' file.txt

Ersetzen der IP-Adresse "10.0.1.1" in allen Dateien im Verzeichnis "/etc" (z. B. wenn gerade eine Maschine geklont wurde) durch die Adresse "10.0.5.5".

$ for i in $(grep -rlIs "10.0.1.1" /etc); do echo "changing file $i"; \
    sed 's/10.0.1.1/10.0.5.5/' $i > sed.tmp; mv sed.tmp $i; done

Einfügen einer Zeile über einem bestimmten Suchmuster.

$ echo "Das ist ein Text\nmit einem SUCHMUSTER" | \
    sed -e '/SUCHMUSTER/{;i\' -e 'der auch in einer Datei stehen könnte' -e '}'
der auch in einer Datei stehen könnte
Das ist ein Text\nmit einem SUCHMUSTER

Auskommentieren aller mit Kleinbuchstaben beginnenden Zeilen in der Datei "file.txt" durch das Zeichen "#".

$ sed "/^[a-z]/s/^/#/" file.txt

Platzhalter

Gegeben sei eine Datei "file" mit folgendem Inhalt.

361
405

Die in der Datei enthaltenen Nummern werden im folgenden Befehl anstelle des Platzhalters "\1" eingesetzt.

$ sed 's/\(.*\)/0000:\1\n9998:\1\n9999:\n/' file > newfile
$ more newfile
0000:361
9998:361
9999:

0000:405
9998:405
9999:

Weblinks

Herausgeber Sprache Webseitentitel Anmerkungen
Sourceforge eng The SED $HOMEwbm
Wikipedia ger Sed (Unix)wbm Enzyklopädischer Artikel
eng The sed FAQwbm
Eric Pement eng Handy oneliners for sedwbm
Stefan Waidele ger sed-Einzeiler : deutsche Übersetzungwbm
Vimperl ger Sedwbm Einige Tips