Die Benutzung von sed in FreeBSD

Es gibt viele Gründe, den stream editor (sed)zu benutzen. Zum Beispiel um Config-Dateien von nginx zu bearbeiten, wenn dort Einträge zu ändern sind, die sich nicht über Variablen hinterlegen oder auswerten lassen.

Angabe des Schalters -i

Laut den tausenden von Codebeispielen im Internet müsste man zur Änderung von ‘xyz.de’ in ‘xyz.cloud’ sed so benutzen:

sed -i 's/xyz.de/xyz.cloud/g' www.conf

Das quittiert sed in FreeBSD aber mit

sed: 1: "www.conf": invalid command code w

Der Schalter -i steht für “in-place”, also dafür, ein Backup anzulegen, die Datei direkt zu bearbeiten und zu speichern.

Nach kurzem Blick in die Manpage von sed(1) findet man heraus, dass das Programm auf FreeBSD anders arbeitet.

Im Gegensatz zu Linux, welches automatisch ein Backup mit einer fest definierten Dateierweiterung anlegt, erwartet FreeBSD nach dem Schalter aber eine “extension”, wie das Backup zu benennen ist. So kann hier

sed -i '' 's/xyz.de/xyz.cloud/g' www.conf

angegeben werden. Das kann ich aber nicht empfehlen, da in diesem Fall kein Backup angelegt wird!

Besser ist es, sed wie folgt aufzurufen, damit das Backup als ‘www.conf.bak’ angelegt, dann geändert und die bearbeitete Datei unter dem ursprünglichen Namen abgelegt wird:

sed -i '.bak' 's/xyz.de/xyz.cloud/g' www.conf

Besonderheit: Trennzeichen

Der search/replace-String hat übrigens noch eine Besonderheit: Nämlich der Aufbau. Der String wird aufgebaut als s/Suchstring/Ersatzstring um das erste Vorkommen zu ersetzen oder als s/Suchstring/Ersatzstring/g, wenn alle Vorkommen ersetzt werden sollen (das g steht für global, bezogen auf die Datei).

Besonders das Trennzeichen (im Beispiel /) ist hier interessant. Üblicherweise wird dafür der Slash / genommen. In manchen Situation, z.B. in URLs ist das so nicht möglich. Dann müssen die Slashs in der URL entweder mit dem Backslash als \/ maskiert werden, oder man benutzt einen anderen Trenner. sed akzeptiert jedes Zeichen als Trennzeichen.

Beispiele

Ungültig:

sed -i '.bak' 's/xyz.de/index.html/xyz.cloud/index.php/g' www.conf

Gültig:

sed -i '.bak' 's/xyz.de\/index.html/xyz.cloud\/index.php/g' www.conf
sed -i '.bak' 's%xyz.de/index.html%xyz.cloud/index.php%g' www.conf

Kommentar verfassen