sed-Befehl: Zeichenketten ersetzen, Zeilen löschen und die Option -i verwenden

TestumgebungRHEL-FamilieAlmaLinux 9.8root-KontoGeprüft am 2026-10-28

Der sed-Befehl ist ein Linux-Werkzeug, das eine Datei Zeile für Zeile liest und Ersetzungen, Löschungen und Einfügungen ausführt, sodass du Werte in einer Konfigurationsdatei ändern kannst, ohne einen Editor zu öffnen. Als wir sed auf einem AlmaLinux-9-Server auf eine Kopie der WordPress-Datei wp-config.php angewendet haben, konnten wir mit -i.bak den Datenbanknamen ändern und das Original behalten.

Die Fehlermeldungen in diesem Artikel sind unverändert so abgedruckt, wie sie unter einer englischen locale ausgegeben wurden.

1️⃣ Grundlegende Verwendung des sed-Befehls und Ersetzen mit s

Der am häufigsten genutzte Befehl s ersetzt Zeichenketten in der Form [s/Suchtext/Ersatztext/]. Er ersetzt in einer Zeile nur den ersten Treffer.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/'
https://example.com http://example.com/blog

Um alle Treffer in einer Zeile zu ersetzen, hängst du das Flag g an.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/g'
https://example.com https://example.com/blog

Hängst du einen Dateinamen an, liest sed diese Datei und gibt das geänderte Ergebnis aus. In einer Kopie von wp-config-sample.php aus WordPress unter dem Namen wp-config.php haben wir den Wert von DB_USER geändert und nur diese Zeile mit grep geprüft.

sed 's/username_here/wp_user/' wp-config.php | grep DB_USER
define( 'DB_USER', 'wp_user' );

Weil sich der Wert in der Ausgabe geändert hat, liegt die Annahme nahe, auch die Datei sei geändert. sed gibt das Ergebnis ohne Option aber nur auf dem Bildschirm aus und lässt die Originaldatei unverändert. Als wir dieselbe Zeile erneut in der Datei gesucht haben, stand dort noch der ursprüngliche Wert.

grep DB_USER wp-config.php
define( 'DB_USER', 'username_here' );

Um auch die Originaldatei zu ändern, verwendest du die Option -i aus 4️⃣.

2️⃣ Zeilen in sed nach Zeilennummer und Muster auswählen (-n, p)

Ohne Adresse gilt der Befehl s für alle Zeilen. Für bestimmte Zeilen schreibst du daher eine Zeilennummer oder ein Muster als Adresse vor den Befehl. -n schaltet die automatische Ausgabe ab und p gibt die ausgewählten Zeilen aus. Zusammen erscheint nur Zeile 23.

sed -n '23p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

Verbindest du zwei Zeilennummern mit einem Komma, erscheint dieser Bereich. Die Zeilen 23 bis 32 sind der Abschnitt mit den Einstellungen für Datenbankname, Benutzer, Passwort und Host.

sed -n '23,32p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

/** Database username */
define( 'DB_USER', 'username_here' );

/** Database password */
define( 'DB_PASSWORD', 'password_here' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

Schreibst du statt einer Zeilennummer ein Muster zwischen Schrägstriche, werden alle Zeilen mit diesem Muster ausgewählt.

sed -n '/DB_/p' wp-config.php
define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

Der Befehl [=] gibt die Nummer der ausgewählten Zeile aus. Die Adresse $ steht für die letzte Zeile, daher zeigt [$=] die Gesamtzahl der Zeilen in der Datei.

sed -n '/DB_HOST/=' wp-config.php
32
sed -n '$=' wp-config.php
102

Eine Adresse kann auch vor dem Befehl s stehen. Unten siehst du das Ergebnis, wenn localhost nur in Zeile 32 geändert und mit dem Flag p nur die geänderte Zeile ausgegeben wird.

sed -n '32s/localhost/127.0.0.1/p' wp-config.php
define( 'DB_HOST', '127.0.0.1' );

Als wir p ohne -n ausgeführt haben, erschien die ausgewählte Zeile ein weiteres Mal. sed liest die Zeilen einzeln in den Pattern Space, führt die Befehle aus und gibt den Pattern Space danach automatisch aus. Deshalb erscheint die mit p ausgegebene Zeile 2 durch die automatische Ausgabe noch einmal.

sed '2p' wp-config.php | head -n 4
<?php
/**
/**
 * The base configuration for WordPress

Diese Arbeitsweise, Zeile für Zeile zu lesen und zu verarbeiten, gleicht einem Fließband in einer Fabrik, das Teile einzeln auf die Werkbank legt, bearbeitet und zum nächsten Teil weitergeht.

Was jeder Befehl pro Zeile ausgibt, kannst du im Diagramm unten Schritt für Schritt vergleichen.

🧭 sed Pattern Space und automatische Ausgabe: p, d in Zeile 2
Erklär-Diagramm
⚙️ Befehl
$ sed '2p'-n '2p''2d' wp-config.php
Gelesene ZeileBefehl ausführen und Ausgabe
Zeile 1 → Pattern Space<?php
➜
Weicht von Adresse 2 ab: kein BefehlAutomatische Ausgabe 1-malWegen -n keine Ausgabe
Zeile 2 → Pattern Space/**
➜
Passt zu Adresse 2: p ausführenPasst zu Adresse 2: d ausführen1-mal durch p + 1-mal automatischNur 1-mal durch pPattern Space leeren, nächste Zeile
Zeile 3 → Pattern Space * The base configuration for WordPress
➜
Weicht von Adresse 2 ab: kein BefehlAutomatische Ausgabe 1-malWegen -n keine Ausgabe
🖥️ Was auf dem Bildschirm erscheint (Zeilen 1~3)
<?php/**/** * The base configuration for WordPress
p gibt den Pattern Space noch einmal aus. Ohne -n erscheint Zeile 2 daher zweimal.
-n schaltet die automatische Ausgabe ab, daher erscheint nur die mit p ausgewählte Zeile 2 einmal.
d leert den Pattern Space und geht zur nächsten Zeile, daher wird Zeile 2 nicht automatisch ausgegeben.

3️⃣ Zeilen mit dem sed-Befehl löschen und einfügen (d, i, a)

d löscht die ausgewählten Zeilen. Um die nginx-Beispielkonfiguration unten ohne Kommentarzeilen zu sehen, wählst du mit dem Muster [^ *#] Zeilen aus, die mit # beginnen oder vor # nur Leerzeichen haben.

cat example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}
sed '/^ *#/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

Verbindest du Befehle mit einem Semikolon, wird auch [^$] gelöscht, das für eine Leerzeile steht. Die zwei Leerzeilen, die nach dem Löschen der Kommentare übrig waren, verschwanden, und nur die Konfigurationszeilen blieben.

sed '/^ *#/d; /^$/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php index.html;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

i fügt Text vor der ausgewählten Zeile ein, a danach. Das Ergebnis, wenn vor Zeile 1 eine Kommentarzeile eingefügt wird, siehst du unten.

sed '1i # managed by sed' example.conf | head -n 3
# managed by sed
# example.com
server {

Es liegt die Annahme nahe, dass eingerückter Text nach a samt Einrückung eingefügt wird. GNU sed überspringt die Leerzeichen direkt nach a aber und fügt nur den Text ein.

sed '/index index.php/a    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

Um die Einrückung zu erhalten, setzt du nach a einen Backslash. Ab dem Leerzeichen hinter dem Backslash zählt alles als Text.

sed '/index index.php/a\    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

c ersetzt die ausgewählte Zeile komplett. Unten siehst du die ersten vier Zeilen des Ergebnisses, wenn die Zeile listen 80 in 8080 geändert wird.

sed '/listen 80;/c\    listen 8080;' example.conf | head -n 4
# example.com
server {
    listen 8080;
    server_name example.com www.example.com;

4️⃣ Dateien mit sed -i direkt bearbeiten und Name der Sicherungsdatei

-i speichert das Ergebnis statt auf dem Bildschirm in der Originaldatei. Text direkt nach -i wird ans Ende des Namens der Sicherungsdatei gehängt. wp-config.php und andere Dateien, die die Website liest, bearbeitest du mit -i.bak und behältst das Original.

cp wp-config-sample.php wp-config.php
sed -i.bak 's/database_name_here/wordpress_db/' wp-config.php

Mit -i erscheint auf dem Bildschirm nichts, also prüfst du die Dateien mit ls -l.

ls -l wp-config.php*
-rw-r--r-- 1 root root 3333 Oct 28 15:13 wp-config.php
-rw-r--r-- 1 root root 3339 Oct 28 15:13 wp-config.php.bak

Die bearbeitete Datei und die .bak-Datei liegen nun nebeneinander. Die Größe ist um 6 Byte gesunken, weil database_name_here zum kürzeren wordpress_db wurde. Vergleichst du beide Dateien mit diff, siehst du nur die geänderte Zeile.

diff wp-config.php.bak wp-config.php
23c23
< define( 'DB_NAME', 'database_name_here' );
---
> define( 'DB_NAME', 'wordpress_db' );

Die geänderte Zeile ist die eine DB_NAME-Zeile in Zeile 23.

Sind mehrere Werte zu ändern, verkettest du Skripte mit -e und führst sie auf einmal aus.

sed -i -e 's/username_here/wp_user/' -e 's/password_here/wp_pass/' wp-config.php
grep -n -e DB_USER -e DB_PASSWORD wp-config.php
26:define( 'DB_USER', 'wp_user' );
29:define( 'DB_PASSWORD', 'wp_pass' );

Schreibst du -i und -e zusammen als [-ie], wird das e als Teil des Sicherungsnamens gelesen, und wie unten entstand eine Datei wp-config.phpe.

sed -ie 's/127.0.0.1/localhost/' wp-config.php
ls wp-config.php*
wp-config.php
wp-config.php.bak
wp-config.phpe

-i schreibt den bearbeiteten Inhalt in eine neue Datei und benennt sie dann in den ursprünglichen Namen um, daher unterscheidet sich die inode-Nummer der Datei vor und nach dem Aufruf.

ls -i wp-config.php
207618887 wp-config.php
sed -i 's/localhost/127.0.0.1/' wp-config.php
ls -i wp-config.php
207618883 wp-config.php

Die inode-Nummer änderte sich von 207618887 vor dem Aufruf zu 207618883.

Fehlt die Datei oder der Dateiname, endet sed mit dem Fehler unten und keine Datei wird geändert.

sed -i 's/x/y/' no-such.php
sed: can't read no-such.php: No such file or directory
sed -i 's/x/y/'
sed: no input files

5️⃣ Reguläre Ausdrücke in sed, Trennzeichen ändern und Optionen

🔲 Reguläre Ausdrücke und Trennzeichen ändern

Änderst du einen Wert mit Schrägstrichen wie einen Pfad, vermischen sich das Trennzeichen des Befehls s und die Schrägstriche im Wert. Jeder Schrägstrich im Wert braucht daher einen Backslash.

sed -n 's/\/var\/www\/example.com/\/srv\/www\/example.com/p' example.conf
    root /srv/www/example.com;

Das Zeichen direkt nach s wird zum Trennzeichen. Wechselst du zu |, das im Wert nicht vorkommt, ergibt sich dasselbe Ergebnis ohne Backslashes.

sed -n 's|/var/www/example.com|/srv/www/example.com|p' example.conf
    root /srv/www/example.com;

Der Punkt (.) in einem Muster passt auf jedes einzelne Zeichen. Unten siehst du, wie ein Muster für example.com auch exampleXcom geändert hat.

echo 'exampleXcom example.com' | sed 's/example.com/test.org/g'
test.org test.org

Um einen Punkt wörtlich zu suchen, setzt du einen Backslash davor.

echo 'exampleXcom example.com' | sed 's/example\.com/test.org/g'
exampleXcom test.org

Einen in Klammern gefassten Teil rufst du im Ersatztext mit [\1] wieder auf. Mit -E nutzt du Klammern und + ohne Backslashes. Unten siehst du das Ergebnis, wenn die Zahl nach listen bleibt und default_server angehängt wird.

sed -nE 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

Ohne -E liest dasselbe Skript die Klammern als Text, und es kommt ein Fehler, dass keine aufzurufende Gruppe existiert. Ohne -E brauchen Klammern und + einen Backslash.

sed -n 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
sed: -e expression #1, char 46: invalid reference \1 on `s' command's RHS
sed -n 's/listen \([0-9]\+\);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

[&] im Ersatztext steht für den gesamten Text, auf den das Muster gepasst hat. So kannst du vor den Treffer # setzen und die Zeile zu einem Kommentar machen.

sed -n 's/server_name .*;/# &/p' example.conf
    # server_name example.com www.example.com;

🔲 Optionen des sed-Befehls

📌 Wichtige Optionen: Ergebnisse aus diesem Artikel

OptionWas es tutErgebnis in diesem Artikel
-nSchaltet die automatische Ausgabe ab und gibt nur mit p ausgewählte Zeilen aussed -n '23p' zeigt nur Zeile 23; ohne -n gibt 2p Zeile 2 zweimal aus
-iSpeichert das Ergebnis statt auf dem Bildschirm in der Originaldatei (Text direkt danach kommt ans Ende des Sicherungsnamens)-i.bak erzeugt wp-config.php.bak; die inode-Nummer ändert sich nach dem Aufruf
-eVerkettet mehrere Skripte und führt sie auf einmal ausDB_USER und DB_PASSWORD ändern sich auf einmal; zusammengeschrieben als -ie entsteht eine Sicherung wp-config.phpe
-ENutzt erweiterte reguläre Ausdrücke (ohne Backslash bei Klammern und +)Gibt listen 80 default_server; aus; dasselbe Skript ohne -E ergibt den Fehler [invalid reference]
--follow-symlinksBearbeitet zusammen mit -i die Originaldatei, auf die der Link zeigtOhne die Option entsteht anstelle des Links eine normale Datei und das Original bleibt; mit ihr ändert sich der Originalwert

📎 Weitere Optionen: laut offiziellem Handbuch

OptionWas es tut
-fLiest das Skript aus einer Datei und führt es aus
-rErweiterte reguläre Ausdrücke wie -E (portabler ist -E)
-sBehandelt mehrere Dateien einzeln statt als einen fortlaufenden Strom
-zTrennt Zeilen mit dem Nullzeichen statt mit dem Zeilenumbruch
-uLiest die Eingabe in kleineren Mengen und gibt die Ausgabe häufiger aus
--posixSchaltet alle GNU-Erweiterungen ab
--debugGibt den Ablauf der Ausführung ausführlich aus

🔲 sed-Befehl-Simulator

Im Arbeitsordner des Simulators unten liegen eine Kopie von wp-config.php und example.conf. Du kannst die bisherigen Befehle selbst eingeben und mit -i geänderte Dateien mit ls -l und diff prüfen.

sed-Befehl-SimulatorGNU sed
[root@server work]#
Mit den Tasten ↑↓ holst du zuvor eingegebene Befehle zurück.

🔢 FAQ & empfohlene Inhalte

wp-config-sample.php aus WordPress hat CRLF-Zeilenenden, daher steht direkt vor dem Zeilenende ein unsichtbares [\r]. Mit [/false );$/] wurde keine Zeile ausgegeben, und in einer Kopie, aus der [\r] mit [s/\r$//] entfernt wurde, fand dasselbe Muster die Zeile WP_DEBUG.

-i legt anstelle des Links eine neue normale Datei an und speichert dort, daher blieb das Original, auf das der Link zeigte, unverändert. Um die Originaldatei zu bearbeiten, gibst du zusätzlich [--follow-symlinks] an. Dann blieb der Link bestehen und der Originalwert änderte sich.

Auch eine mit NEW=wp_user gesetzte Variable ersetzt die Shell in einfachen Anführungszeichen nicht, und [$NEW] landet wörtlich im Text. Stand das Skript in doppelten Anführungszeichen, ersetzte die Shell die Variable zuerst, und an der Stelle von [$NEW] stand wp_user.

🧭 Empfohlene Artikel zu Textbefehlen 9 Beiträge · 2 Referenzen
🗂️ Befehle zum Anzeigen · Bearbeiten von Text
📄 grep-Befehl 📄 sort-Befehl 📄 uniq-Befehl 📄 tee-Befehl 📄 sed-Befehl
📄 cat-Befehl 📄 less-Befehl 📄 head · tail-Befehle 📄 vi · vim-Befehle

ℹ️ Affiliate-Hinweis
Die Inhalte dieser Website enthalten Affiliate-Links. Kauft ein Besucher über einen dieser Links ein Produkt oder eine Dienstleistung, erhält die Website vom Verkäufer eine Provision. Der Betrag, den der Käufer zahlt(bei Aktionsrabatten sinkt er ↓), steigt dadurch nicht. Angegebene Preise, Rabatte und Lagerbestände entsprechen dem Stand bei Erstellung und können abweichen; prüfe sie daher vor dem Kauf beim Verkäufer. Produkte werden nach eigenen Kriterien ausgewählt und bewertet, und Provisionen beeinflussen weder die Reihenfolge noch den Inhalt der Bewertungen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Beweisen Sie, dass Sie ein Mensch sind: 8   +   7   =