Bei der Arbeit mit Textdateien müssen Sie häufig Textzeichenfolgen in einer oder mehreren Dateien suchen und ersetzen.
sed
ist ein s behandeln ed itor. Es kann grundlegende Textmanipulationen an Dateien und Eingabeströmen wie Pipelines durchführen. Mit sed
können Sie Wörter und Zeilen suchen, finden und ersetzen, einfügen und löschen. Es unterstützt grundlegende und erweiterte reguläre Ausdrücke, mit denen Sie komplexe Muster abgleichen können.
In diesem Artikel sprechen wir darüber, wie man Strings mit sed
findet und ersetzt . Wir zeigen Ihnen auch, wie Sie ein rekursives Suchen und Ersetzen durchführen.
String suchen und durch sed
ersetzen #
Es gibt mehrere Versionen von sed
, mit einigen funktionalen Unterschieden zwischen ihnen. macOS verwendet die BSD-Version, während die meisten Linux-Distributionen GNU sed
enthalten standardmäßig vorinstalliert. Wir verwenden die GNU-Version.
Die allgemeine Form des Suchens und Ersetzens von Text mit sed
hat folgende Form:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i
- Standardmäßigsed
schreibt seine Ausgabe auf die Standardausgabe. Diese Option teiltsed
mit um Dateien an Ort und Stelle zu bearbeiten. Wenn eine Erweiterung angegeben wird (z. B. -i.bak), wird eine Sicherungskopie der Originaldatei erstellt.s
- Der Ersatzbefehl, wahrscheinlich der am häufigsten verwendete Befehl in sed./ / /
- Trennzeichen. Es kann ein beliebiges Zeichen sein, aber normalerweise der Schrägstrich (/
) Zeichen verwendet.SEARCH_REGEX
- Normale Zeichenfolge oder ein regulärer Ausdruck, nach dem gesucht werden soll.REPLACEMENT
- Die Ersetzungszeichenfolge.g
- Globale Ersatzflagge. Standardmäßigsed
liest die Datei Zeile für Zeile und ändert nur das erste Vorkommen vonSEARCH_REGEX
auf einer Linie. Wenn das Ersetzungs-Flag bereitgestellt wird, werden alle Vorkommen ersetzt.INPUTFILE
- Der Name der Datei, auf der Sie den Befehl ausführen möchten.
Es empfiehlt sich, das Argument in Anführungszeichen zu setzen, damit sich die Shell-Metazeichen nicht ausdehnen.
Mal sehen, wie wir den sed
verwenden können Befehl zum Suchen und Ersetzen von Text in Dateien mit einigen der am häufigsten verwendeten Optionen und Flags.
Zu Demonstrationszwecken verwenden wir die folgende Datei:
file.txt123 Foo foo foo
foo /bin/bash Ubuntu foobar 456
Wenn der g
Flag weggelassen wird, wird nur die erste Instanz des Suchstrings in jeder Zeile ersetzt:
sed -i 's/foo/linux/' file.txt
123 Foo linux foo
linux /bin/bash Ubuntu foobar 456
Mit dem globalen Ersatz-Flag sed
ersetzt alle Vorkommen des Suchmusters:
sed -i 's/foo/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456
Wie Sie vielleicht bemerkt haben, ist der Teilstring foo
innerhalb der foobar
string wird auch im vorherigen Beispiel ersetzt. Wenn dies nicht das gewünschte Verhalten ist, verwenden Sie den Wortgrenzenausdruck (\b
) an beiden Enden der Suchzeichenfolge. Dadurch wird sichergestellt, dass die Teilwörter nicht übereinstimmen.
sed -i 's/\bfoo\b/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu foobar 456
Verwenden Sie I
, um die Groß-/Kleinschreibung des Musters zu ignorieren Flagge. Im folgenden Beispiel verwenden wir sowohl den g
und I
Flaggen:
sed -i 's/foo/linux/gI' file.txt
123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456
Wenn Sie eine Zeichenfolge suchen und ersetzen möchten, die das Trennzeichen (/
) müssen Sie den umgekehrten Schrägstrich verwenden (\
), um dem Schrägstrich zu entkommen. Zum Beispiel um /bin/bash
zu ersetzen mit /usr/bin/zsh
würden Sie verwenden
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
Die einfachere und viel besser lesbare Option ist die Verwendung eines anderen Trennzeichens. Die meisten Leute verwenden den vertikalen Strich (|
) oder Doppelpunkt (:
), aber Sie können jedes andere Zeichen verwenden:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456
Sie können auch reguläre Ausdrücke verwenden. Zum Beispiel, um alle 3-stelligen Zahlen zu suchen und sie durch die Zeichenfolge number
zu ersetzen Sie würden verwenden:
sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
number Foo foo foo
foo /bin/bash demo foobar number
Eine weitere nützliche Funktion von sed ist, dass Sie das kaufmännische Und-Zeichen &
verwenden können was dem angepassten Muster entspricht. Das Zeichen kann mehrfach verwendet werden.
Wenn Sie beispielsweise geschweifte Klammern hinzufügen möchten {}
Geben Sie um jede 3-stellige Zahl herum Folgendes ein:
sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
{123} Foo foo foo
foo /bin/bash demo foobar {456}
Nicht zuletzt ist es immer eine gute Idee, eine Sicherungskopie zu erstellen, wenn Sie eine Datei mit sed
bearbeiten . Geben Sie dazu einfach eine Erweiterung für die Sicherungsdatei an -i
an Möglichkeit. Zum Beispiel, um die file.txt
zu bearbeiten und speichern Sie die Originaldatei als file.txt.bak
Sie würden verwenden:
sed -i.bak 's/foo/linux/g' file.txt
Um sicherzustellen, dass die Sicherung erstellt wird, listen Sie die Dateien mit dem ls
auf Befehl:
ls
file.txt file.txt.bak
Rekursives Suchen und Ersetzen #
Manchmal möchten Sie vielleicht Verzeichnisse rekursiv nach Dateien durchsuchen, die eine Zeichenfolge enthalten, und die Zeichenfolge in allen Dateien ersetzen. Dies kann mit Befehlen wie find
erfolgen oder grep
um rekursiv Dateien im Verzeichnis zu finden und die Dateinamen an sed
weiterzuleiten .
Der folgende Befehl sucht rekursiv nach Dateien im aktuellen Arbeitsverzeichnis und übergibt die Dateinamen an sed
.
find . -type f -exec sed -i 's/foo/bar/g' {} +
Um Probleme mit Dateien zu vermeiden, die Leerzeichen in ihren Namen enthalten, verwenden Sie -print0
Option, die find
mitteilt um den Dateinamen gefolgt von einem Nullzeichen auszugeben und die Ausgabe an sed
zu leiten mit xargs -0
:
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
Um ein Verzeichnis auszuschließen, verwenden Sie -not -path
Möglichkeit. Wenn Sie beispielsweise eine Zeichenfolge in Ihrem lokalen Git-Repo ersetzen, um alle Dateien auszuschließen, die mit einem Punkt beginnen (.
), verwenden Sie:
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'
Wenn Sie Text nur in Dateien mit einer bestimmten Erweiterung suchen und ersetzen möchten, verwenden Sie:
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
Eine andere Möglichkeit ist die Verwendung von grep
Befehl, um rekursiv alle Dateien zu finden, die das Suchmuster enthalten, und leitet dann die Dateinamen an sed
weiter :
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'
Schlussfolgerung #
Obwohl es zunächst kompliziert und komplex erscheinen mag, suchen und ersetzen Sie Text in Dateien mit sed
ist ganz einfach.
Um mehr über sed
zu erfahren Befehle, Optionen und Flags finden Sie im GNU-Sed-Handbuch und im Grymoire-Sed-Tutorial.
Wenn Sie Fragen oder Feedback haben, können Sie gerne einen Kommentar hinterlassen.