Der Befehl sed ist ein Stream-Editor, der Text in Dateien suchen und ersetzen kann. Anders als in einem Texteditor passiert das direkt auf der Kommandozeile, was besonders bei der Verarbeitung mehrerer Dateien oder in Skripten nützlich ist.
Syntax
Die Grundstruktur für das Suchen und Ersetzen mit sed sieht so aus:
sed -i 's/SUCHBEGRIFF/ERSETZUNG/g' DATEI
s- Der Substitutions-Befehl (engl. substitute)./- Das Trennzeichen zwischen den Bestandteilen. Du kannst auch andere Zeichen verwenden (dazu später mehr).SUCHBEGRIFF- Der Text oder reguläre Ausdruck, nach dem gesucht wird.ERSETZUNG- Der Text, der eingesetzt werden soll.g- Ersetzt alle Treffer in jeder Zeile (global). Ohne dieses Flag wird nur der erste Treffer pro Zeile ersetzt.-i- Bearbeitet die Datei direkt (in-place). Ohne diese Option gibtseddas Ergebnis nur auf der Standardausgabe aus.
Hinweis: macOS verwendet die BSD-Version von sed, die sich etwas anders verhält. Dort erfordert -i ein zusätzliches Argument für die Backup-Endung. Mit -i '' (leerer String) arbeitest du ohne Backup.
Einfaches Suchen und Ersetzen
Für die folgenden Beispiele verwenden wir eine Testdatei:
echo -e "Server: foo\nPort: 8080\nfoo_user=admin\nfoobar_path=/home/foo" > config.txt
Um foo durch bar zu ersetzen:
sed -i 's/foo/bar/g' config.txt
Das Ergebnis:
Server: bar
Port: 8080
bar_user=admin
barbar_path=/home/bar
Ohne das g-Flag wird nur das erste Vorkommen pro Zeile ersetzt. Wenn eine Zeile mehrere Treffer enthält, bleiben die restlichen unverändert.
Nur ganze Wörter ersetzen
Im vorherigen Beispiel wurde auch foobar zu barbar, weil foo als Teilstring gefunden wurde. Um nur vollständige Wörter zu ersetzen, verwendest du Wortgrenzen:
sed -i 's/\bfoo\b/bar/g' config.txt
Jetzt bleibt foobar unverändert, während alleinstehende foo ersetzt werden.
Groß- und Kleinschreibung ignorieren
Standardmäßig unterscheidet sed zwischen Groß- und Kleinschreibung. Mit dem I-Flag suchst du unabhängig von der Schreibweise:
sed -i 's/error/FEHLER/gI' logfile.txt
Dieser Befehl ersetzt error, Error, ERROR und alle anderen Varianten durch FEHLER.
Pfade und Sonderzeichen ersetzen
Wenn dein Suchbegriff Schrägstriche enthält, wird die Syntax unübersichtlich:
sed -i 's/\/usr\/local\/bin/\/opt\/bin/g' script.sh
Die bessere Lösung: Verwende ein anderes Trennzeichen. Die meisten nutzen | oder #:
sed -i 's|/usr/local/bin|/opt/bin|g' script.sh
Das ist deutlich lesbarer und funktioniert genauso.
Mit regulären Ausdrücken arbeiten
sed unterstützt reguläre Ausdrücke im Suchbegriff. Um alle dreistelligen Zahlen durch XXX zu ersetzen:
sed -i 's/\b[0-9]\{3\}\b/XXX/g' daten.txt
Das &-Zeichen in der Ersetzung steht für den gefundenen Text. Um Zahlen in Klammern zu setzen:
sed -i 's/\b[0-9]\{3\}\b/(&)/g' daten.txt
Aus Port: 443 wird dann Port: (443).
Backup vor dem Ersetzen erstellen
Bei wichtigen Dateien ist ein Backup sinnvoll. Gib dazu eine Dateiendung nach -i an:
sed -i.bak 's/alt/neu/g' wichtig.conf
sed erstellt automatisch wichtig.conf.bak mit dem ursprünglichen Inhalt, bevor die Änderungen angewendet werden.
Rekursiv in mehreren Dateien ersetzen
Um Text in allen Dateien eines Verzeichnisses zu ersetzen, kombinierst du find mit sed:
find /var/www -type f -name "*.html" -exec sed -i 's/http:/https:/g' {} +
Dieser Befehl durchsucht alle HTML-Dateien unter /var/www und ersetzt http: durch https:.
Für Dateien mit Leerzeichen im Namen ist diese Variante sicherer:
find . -type f -name "*.conf" -print0 | xargs -0 sed -i 's/localhost/127.0.0.1/g'
Die Option -print0 und xargs -0 verwenden Nullzeichen als Trenner, was Probleme mit Sonderzeichen in Dateinamen vermeidet.
Bestimmte Verzeichnisse ausschließen
Um Verzeichnisse wie .git bei der rekursiven Suche zu überspringen:
find . -type f -not -path '*/.git/*' -name "*.py" -print0 | xargs -0 sed -i 's/DEBUG=True/DEBUG=False/g'
Nur Dateien mit Treffern bearbeiten
Mit grep kannst du erst prüfen, welche Dateien den Suchbegriff enthalten:
grep -rlZ 'alter_wert' . | xargs -0 sed -i 's/alter_wert/neuer_wert/g'
Die Option -l gibt nur Dateinamen aus, -Z verwendet Nullzeichen als Trenner.
Zusammenfassung
sed ersetzt Text in Dateien direkt auf der Kommandozeile. Die wichtigsten Punkte:
- Mit
s/suchen/ersetzen/gersetzt du alle Vorkommen - Die Option
-ibearbeitet Dateien direkt,-i.bakerstellt vorher ein Backup - Alternative Trennzeichen wie
|machen Pfade lesbarer - Mit
\bbegrenzt du die Suche auf ganze Wörter - In Kombination mit
findersetzt du rekursiv in mehreren Dateien