In einem früheren Artikel habe ich behandelt, wie man Text mit grep
manipuliert . Wenden Sie sich nun dem sed
zu (Stream-Editor), der sich am besten für die Verwendung in Pipelines eignet (Daten, die aus einer Pipe stammen). Der sed
kann verwendet werden, um den Inhalt einer Datei zu drucken, eine Zeile (oder mehrere Zeilen) zu ersetzen und dann die Datei zu speichern. Im Gegensatz zu grep
, sed
kann eine Zeile oder mehrere Zeilen in einer Datei ersetzen und einen in-place durchführen Update dieser Datei.
Das einfachste sed
Aufruf beim Ersetzen von foo
für bar
ist:
$ sed 's/foo/bar/' inputfile
Beispiel:Kommentare entfernen
Während grep
Ausgabe auf dem Bildschirm formatieren kann, ist es nicht möglich, eine Datei an Ort und Stelle zu ändern. Dazu benötigen Sie einen Dateieditor wie ed
. Seit ed
nicht Teil dieses Artikels ist, verwenden Sie sed
um dasselbe zu erreichen wie mit grep
im ersten Beispiel des vorherigen Artikels. Ändern Sie dieses Mal die /etc/fstab
Datei an Ort und Stelle, indem Sie den -i
übergeben Flag zu sed
. Ohne das -i
flag , würden Sie nur sehen, was geändert worden wäre.
Es wird empfohlen, immer sed
auszuführen ohne das -i
Flag, nur um sicherzustellen, dass das Ergebnis, das es erzeugt, erwartet wird. Der sed
Utility bietet auch das -i.bak
Flag, das vor der Bearbeitung eine Sicherungsdatei erstellt.
Das letzte grep
Befehl für dieses Beispiel war:
$ grep -v '^#' /etc/fstab > ~/fstab_without_comment
Mit sed
, haben Sie:
# sed -i '/^#/d' /etc/fstab
/dev/mapper/VGCRYPTO-ROOT / ext4 defaults,x-systemd.device-timeout=0 1 1
UUID=e9de0f73-ddddd-4d45-a9ba-1ffffa /boot ext4 defaults 1 2
LABEL=SSD_SWAP swap swap defaults 0 0
Beispiel:Nur /etc/passwd
drucken Benutzer
Im grep
Beispiel:Sie haben nur Nutzernamen aus /etc/passwd
gedruckt Datei mit folgendem:
$ grep -Eo '^[a-zA-Z_-]+' /etc/passwd
Sie können dasselbe mit sed
tun wie folgt:
$ sed 's/^\([a-zA-Z_-]\+\).*/\1/' /etc/passwd
Im obigen Beispiel gruppieren Sie eine Übereinstimmung durch Klammern ()
, und drucken Sie dann die übereinstimmende Gruppe mit \1
(Rückverweis), die die erste Gruppe diktiert. Für eine zweite Gruppe würden Sie \2
verwenden , und so weiter.
Beispiel:Ersetzen Sie alle foo
mit bar
In sed
können Sie nach einem Muster suchen und dann nur das Vorkommen ersetzen, das dem Muster entspricht. Um alle Vorkommen in der Datei inputfile1
zu ersetzen von foo
zu bar
Führen Sie global Folgendes aus:
$ sed -i '/foo/bar/g' inputfile1
Beispiel:Ersetzen einer einzelnen Instanz
Nehmen Sie die Datei inputfile2
, die folgenden Inhalt hat:
hello world
second line should be replaced
this line should be replaced later
Angenommen, Sie möchten should
ersetzen mit will
, aber nur für die zweite Zeile. Dieser Befehl gliedert sich wie folgt:
$ sed '/second/s/should/will/' inputfile2
| | | |
| | | with this pattern
| | this pattern
| substitute
Search for the pattern "second"
Diese Ausgabe wird an die Standardausgabe gesendet, anstatt den Inhalt der Datei zu ersetzen. Das Ergebnis sieht so aus:
$ sed '/second/s/should/will/' inputfile2
hello world
second line will be replaced
this line should be replaced later
Der sed
Beim Befehl wird zwischen Groß- und Kleinschreibung unterschieden. Folgendes funktioniert nicht, wenn Sie versuchen, World
zu ersetzen mit there
:
$ echo "Hello World" | sed 's/world/there/'
Hello World
GNU sed
führte ein neues Flag ein, /I
, die Groß- und Kleinschreibung ignoriert und wird Führen Sie die Ersetzung mit demselben Befehl durch:
$ echo "Hello World" | sed 's/world/there/I'
Hello there
Beispiel:Einen Zeilenbereich drucken und beenden
Mit sed
, können Sie auch Zeilen drucken und beenden, nachdem Ihre Kriterien erfüllt sind. Die folgenden Befehle drucken drei Zeilen und beenden sich. Dieser Befehl:
$ sed -n '1,3p' /etc/passwd
entspricht:
$ sed '3q' /etc/passwd
Folgendes wäre falsch:
$ sed '1,3q' /etc/passwd # Wrong. You cannot quit three times
Beispiel:Kommentieren Sie unkommentierte Zeilen aus
Reguläre Ausdrücke können auch mit sed
verwendet werden , wie zuvor gezeigt. Sie haben beispielsweise das folgende kleine Skript:
$ cat test_script
#/usr/bin/env bash
this is the first comment
This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Sie müssen jetzt die erste Zeile überspringen, beginnend mit #!/bin/bash
, und kommentieren Sie die dritte und vierte Zeile aus, aber nicht die fünfte, da diese Zeile bereits auskommentiert ist.
In sed
, können Sie Folgendes verwenden:
$ sed '3,6s/^[^#]/# &/g' test_script
#/usr/bin/env bash
# this is the first comment
# This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Im obigen Befehl wird Folgendes ausgeführt:
3,6s
definiert einen Bereich von Zeile drei bis Zeile sechs./^[^#]/
entspricht allem, was ein Zeichen ist und nicht mit einem Hash beginnt (#
)./# &/g
ersetzt einen Teil, in diesem Fall setzt es ein#
vor der durch&
vorgegebenen Zeile unterschreiben.
Beispiel:Alle Ziffern entfernen
Verschiedene Anwendungen erzeugen Daten in unterschiedlichen Formaten. Mit sed
, können Sie nur die Daten behalten, die Sie verwenden können. Sie haben beispielsweise die folgende Datei (inputfile3
) in diesem Format:
foo1234
bar99128
baz2842
qux12953
discard39120
Vielleicht hat ein Programm das falsche Format generiert oder die Felder zu einem verkettet. Was wäre, wenn Sie nur die Buchstaben behalten und die Ziffern verwerfen möchten? Wie würden Sie dieses Ziel mit sed
erreichen ?
Die Antwort ist wahrscheinlich einfacher als Sie denken:
$ sed 's/\([a-z]*\).*/\1/' inputfile3
foo
bar
baz
qux
discard
Beispiel:Bestimmte Zeilen ändern
Außerdem sed
kann Bereiche auch nach Muster handhaben, was bedeutet, dass Sie einen Start angeben können und ein Ende Zeichenfolge und manipulieren Sie den Bereich. Zum Beispiel:
$ cat inputfile4
hello world
start of the comment
another comment
end of a comment
dont comment this line
nor this line
Der folgende sed
Der Befehl kommentiert Zeilen, die mit start beginnen und endet mit end :
$ sed '/start/,/end/ s/^/# /' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
Entfernen Sie auch die leeren Zeilen.
$ sed '/start/,/end/ s/^/# /;/^$/d' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
sed
bietet noch viel mehr und seine reichhaltigen Funktionen. Um sed
vollständig nutzen zu können Die Fähigkeiten von finden Sie auf der Dokumentationsseite, die Sie hier finden können. Auch eine großartige Informationsquelle zu sed
finden Sie hier.
Zusammenfassung
Wie ich bereits erwähnt habe, verwenden Sie grep
wenn Sie nach einem Muster suchen möchten, entweder in einer Datei oder mehreren Verzeichnissen rekursiv. Verwenden Sie sed
wenn Sie Daten von einer Pipeline empfangen oder Daten spontan manipulieren möchten.
Der sed
Der Befehl ist skriptbasiert und es ist leicht zu erlernen, grundlegende Operationen auszuführen. Alles, was Sie brauchen, ist Übung, insbesondere mit regulären Ausdrücken.