HOWTO · Bash

Zeichenkettenersetzung in Bash

Dieses Tutorial demonstriert das Ersetzen einer Teilzeichenfolge durch eine andere Zeichenfolge in Bash.

Auf dieser Seite

Wähle die Ersetzungsmethode danach aus, wo sich der Text befindet: Die Bash-Parametererweiterung berechnet aus einer Variable in der aktuellen Shell einen Ersatzwert, ohne diese Variable zu verändern. sed verarbeitet Zeilen in einem Datenstrom, und awk eignet sich, wenn die Ersetzung Teil einer datensatzorientierten Verarbeitung ist. Jedes Beispiel ist in sich abgeschlossen; Beispiele zur Dateiverarbeitung legen ihre temporäre Eingabe selbst an.

Eine Ersetzungsmethode auswählen

Für einen Wert, der bereits in einer Bash-Variable gespeichert ist, kommt die Parametererweiterung ohne einen zusätzlichen Prozess aus. Verwende sed für einfache Ersetzungen über Eingabezeilen hinweg, besonders wenn die Eingabe aus einer Pipeline stammt. Verwende awk, wenn derselbe Durchlauf auch Feld-, Datensatz- oder Bedingungslogik benötigt. Liest ein Befehl eine Datei und leitet sein Ergebnis in eine andere Datei um, bleibt die Quelle erhalten; eine Option zur direkten Bearbeitung verändert die Quelle und erfordert besondere Vorsicht.

In den Beispielen ist der wörtliche Text old das Suchmuster und new der Ersatz. Bei der Bash-Parametererweiterung wird der Suchtext nicht automatisch als regulärer Ausdruck behandelt; sed und awk verwenden jedoch ihre eigene Mustersyntax. Enthält die Eingabe oder der Ersatz ein Trennzeichen des jeweiligen Werkzeugs, wähle ein geeignetes anderes Trennzeichen und maskiere es, falls nötig.

Das erste oder jedes Vorkommen mit der Bash-Parametererweiterung ersetzen

Die Bash-Parametererweiterung ersetzt das erste passende Muster mit ${value/pattern/replacement}. Mit einem zweiten Schrägstrich werden alle Vorkommen ersetzt: ${value//pattern/replacement}. In diesen Beispielen wird value lokal zugewiesen. Die ursprüngliche Variable bleibt unverändert; das Ergebnis wird in updated gespeichert.

Führe dieses Beispiel aus:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

value='red old blue old'
updated="${value/old/new}"
printf '%s\n' "$updated"
red new blue old

So ersetzt du alle Vorkommen desselben Werts:

value='red old blue old'
updated="${value//old/new}"
printf '%s\n' "$updated"
red new blue new

Das Muster ist ein Bash-Muster. Zeichen wie * haben darin eine besondere Bedeutung. Maskiere Muster aus Variablen oder Benutzereingaben sorgfältig oder behandle sie auf andere geeignete Weise. Die Parametererweiterung verarbeitet einen einzelnen Shell-Wert; eine Datei bearbeitet sie nicht selbst.

Ein Muster am Ende einer Zeichenkette finden

Die Prozentform ${value%pattern} entfernt den kürzesten passenden Suffix, also den kürzesten passenden Teil am Ende der Zeichenkette; ${value%%pattern} entfernt den längsten passenden Suffix. Sie bedeutet im Allgemeinen nicht „das letzte Vorkommen“ innerhalb einer Zeichenkette finden. Um einen bekannten Suffix zu ersetzen, prüfe oder verarbeite dieses Ende gezielt. Ein .txt-Suffix lässt sich beispielsweise mit einem Muster ersetzen, das genau dieses Ende erfasst:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

filename='report.txt'
updated="${filename%.txt}.md"
printf '%s\n' "$updated"
report.md

Diese Operation betrifft nur einen passenden Suffix. Eine frühere Folge .txt im Namen wird von diesem Muster zum Entfernen des Suffixes nicht erfasst. Falls Namen andere Endungen haben können, prüfe den erwarteten Suffix, bevor du die Umwandlung anwendest, damit du bewusst festlegst, wie ein nicht passender Name behandelt wird.

Textströme und Dateien mit sed bearbeiten

Die Ersetzungsform s/pattern/replacement/ von sed ändert das erste Vorkommen pro Eingabezeile. Füge nach dem letzten Trennzeichen g hinzu, um jedes Vorkommen in jeder Zeile zu ersetzen. Dieser eigenständige Befehl liest eine Datei und schreibt den umgewandelten Text in die Standardausgabe:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

input=$(mktemp)
trap 'rm -f "$input"' EXIT
printf '%s\n' 'old road, old bridge' > "$input"
sed 's/old/new/g' "$input"
new road, new bridge

Um das Ergebnis zu speichern, ohne die Quelle zu verändern, leite die Ausgabe in eine andere Datei um, zum Beispiel output.txt. Verwende für Eingabe und umgeleitete Ausgabe nicht denselben Pfad: Die Shell öffnet das Ziel, bevor sed die Eingabe liest, wodurch die Quelldatei geleert werden kann. Die Option -i bearbeitet eine Datei direkt; die Syntax für Sicherungskopien unterscheidet sich je nach sed-Implementierung. Prüfe den Befehl zuerst anhand einer Kopie oder verwende eine separate Ausgabedatei. Wenn eine direkte Bearbeitung nötig ist, erstelle eine Sicherungskopie.

In einem sed-Ausdruck ist / das übliche Trennzeichen. Enthält ein Suchmuster oder Ersatz dieses Zeichen, kannst du ein anderes Trennzeichen wie | wählen und die Trennzeichen maskieren, die trotzdem im Ausdruck vorkommen. sed-Muster sind reguläre Ausdrücke; auch wörtliche Satzzeichen müssen daher möglicherweise maskiert werden.

Datensatzorientierte Ersetzungen mit awk durchführen

awk kann Vorkommen während der Verarbeitung jedes Eingabedatensatzes ersetzen. gsub ersetzt alle Vorkommen in der ausgewählten Zeichenkette und gibt die Anzahl der Ersetzungen zurück; $0 steht für den aktuellen Datensatz. Dieser Befehl gibt die umgewandelten Datensätze aus, ohne die Eingabedatei zu verändern:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

input=$(mktemp)
trap 'rm -f "$input"' EXIT
printf '%s\n' 'old road, old bridge' > "$input"
awk '{ gsub(/old/, "new", $0); print }' "$input"
new road, new bridge

Leite die Ausgabe in einen neuen Pfad um, wenn du eine umgewandelte Datei speichern möchtest, und prüfe, dass das Ziel nicht mit der Eingabe übereinstimmt. Für awk gelten Regeln für reguläre Ausdrücke und Ersatzzeichenketten. Zeichen mit besonderer Bedeutung müssen daher behandelt werden, wenn die Muster keine festen Literale sind. Wähle awk, wenn die Ersetzung Teil einer datensatzorientierten Verarbeitung ist; für eine einfache Ersetzung in einem Datenstrom ist sed möglicherweise leichter zu lesen.

Häufige Fallstricke und praktische Hinweise

Für mehrere Ersetzungen in einer Variablen kannst du Parametererweiterungen verketten, indem du jedes Ergebnis dem nächsten Wert zuweist, oder einen Durchlauf mit mehreren Ersetzungen in sed oder awk verwenden. Formuliere jede Umwandlung ausdrücklich, damit die Reihenfolge klar ist: Eine frühere Ersetzung kann Text erzeugen, den ein späteres Muster dann erfasst.

Verwende die Parametererweiterung, wenn der Text bereits in einer Bash-Variablen liegt und die Muster einfach sind. So vermeidest du einen externen Befehl. Eine allgemeine Aussage zur Leistung sollte jedoch keine Messung der tatsächlich relevanten Arbeitslast ersetzen. sed eignet sich direkt für Ersetzungen in zeilenorientierten Datenströmen. awk ist nützlich, wenn die Ersetzung mit Feldern, Bedingungen oder anderer Datensatzverarbeitung kombiniert wird. Diese Werkzeuge verwenden unterschiedliche Regeln für Muster und Ersetzungen. Gehe daher nicht davon aus, dass sich ein Muster unverändert von einem Werkzeug auf ein anderes übertragen lässt.

Erhalte vor Änderungen an einer Datei das Original, indem du in ein separates Ziel schreibst oder eine Sicherungskopie anlegst. Prüfe Eingabe- und Ausgabepfade sowie repräsentative Eingaben. Verwende eine direkte Bearbeitung erst, wenn sie erforderlich ist. Das ist besonders bei weit gefassten Mustern wichtig, da eine globale Ersetzung jedes passende Vorkommen in jeder Zeile ändern kann.

Führe das betreffende Beispiel zunächst mit einer Kopie deiner Daten aus und prüfe das Ergebnis, bevor du es auf wichtige Dateien anwendest. Der Artikel enthält keine gemessenen Vergleiche dieser Methoden. Wähle deshalb anhand der Eingabeform, der benötigten Verarbeitung und der Anforderungen an die Dateisicherheit – nicht anhand einer angenommenen Rangfolge bei der Geschwindigkeit.