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äßigsedschreibt seine Ausgabe auf die Standardausgabe. Diese Option teiltsedmit 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äßigsedliest die Datei Zeile für Zeile und ändert nur das erste Vorkommen vonSEARCH_REGEXauf 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.