grep, sed und awk: Beispiele zur Textverarbeitung im Linux-Terminal
grep findet Zeilen nach Muster (grep -rn error /var/log), sed ändert Text im Datenstrom oder in der Datei (sed -i 's/alt/neu/g' datei), awk arbeitet mit Spalten und zählt (awk '{print $1}' access.log). Zusammen in einer Pipeline ersetzen sie ein Skript: grep filtert Zeilen, sed korrigiert Text, awk schneidet Felder aus und aggregiert.
grep, sed und awk sind drei klassische Linux-Werkzeuge zur Textverarbeitung. grep findet Zeilen nach einem Muster, sed ersetzt und löscht Text im Datenstrom, ohne einen Editor zu öffnen, und awk zerlegt Zeilen in Spalten und kann rechnen. Die folgenden grep sed awk beispiele zeigen die Aufgaben, die beim Auswerten von Logs, Konfigurationen und Befehlsausgaben tatsächlich anfallen, dazu typische Fehler.
Wann welches Werkzeug?
Alle drei Werkzeuge lesen Text zeilenweise und schreiben das Ergebnis auf die Standardausgabe. Deshalb lassen sie sich leicht mit | verketten. Der Unterschied liegt in der Aufgabe, die jedes Werkzeug am besten löst.
| Aufgabe | Werkzeug | Beispiel |
|---|---|---|
| Zeilen mit einem Text finden | grep | grep ERROR app.log |
| Text ersetzen | sed | sed 's/http:/https:/g' datei |
| Zeilen nach Nummer löschen oder anzeigen | sed | sed -n '10,20p' datei |
| Eine Spalte herausholen | awk | awk '{print $1}' access.log |
| Summe, Mittelwert, Gruppierung berechnen | awk | awk '{s+=$10} END {print s}' |
Eine einfache Faustregel: Wollen Sie nur filtern, nehmen Sie grep. Wollen Sie Text ändern, nehmen Sie sed. Enthält der Text Spalten oder brauchen Sie Arithmetik, nehmen Sie awk.
grep: Zeilen nach Muster suchen
Grundlegende grep-Beispiele
# Zeilen mit dem Wort error in der Datei
grep error /var/log/syslog
# Ohne Beachtung der Groß- und Kleinschreibung: Error, ERROR, error
grep -i error app.log
# Mit Zeilennummern
grep -n "Connection refused" app.log
# Rekursiv durch ein Verzeichnis, mit Dateinamen
grep -rn "DB_HOST" /etc/myapp/
# Nur die Namen der Dateien, in denen es einen Treffer gibt
grep -rl "TODO" src/
# Umkehren: alles AUSSER Kommentaren und Leerzeilen
grep -v -e '^#' -e '^$' /etc/ssh/sshd_config
# Anzahl der passenden Zeilen zählen
grep -c " 500 " access.log
Die Option -w sucht ein ganzes Wort: grep -w log findet login nicht. Die Option -F schaltet reguläre Ausdrücke ab und sucht die Zeichenkette wörtlich. Das ist praktisch, wenn das Muster Punkte, Klammern oder Sternchen enthält.
Kontext um den Treffer
Ein Fehler im Log ist selten aus einer einzelnen Zeile zu verstehen. Oft braucht man den Stack-Trace oder die Anfrage, die dazu geführt hat. Dafür gibt es Kontext-Optionen:
# 3 Zeilen nach dem Treffer (After)
grep -A 3 "Traceback" app.log
# 2 Zeilen vor dem Treffer (Before)
grep -B 2 "OOM" /var/log/kern.log
# jeweils 5 Zeilen auf beiden Seiten (Context)
grep -C 5 "segfault" /var/log/syslog
grep trennt getrennte Trefferblöcke mit einer Zeile --, sodass die Ausgabe gut lesbar bleibt.
grep und reguläre Ausdrücke
Standardmäßig versteht grep die einfachen regulären Ausdrücke (BRE). Mit -E schalten Sie die erweiterten (ERE) ein, bei denen +, ?, | und Klammern ohne Backslash funktionieren.
| Konstrukt | Bedeutung | Beispiel |
|---|---|---|
^ | Zeilenanfang | grep '^root' /etc/passwd |
$ | Zeilenende | grep 'bash$' /etc/passwd |
. | beliebiges Zeichen | grep 'h.t' |
* | 0 oder mehr Wiederholungen | grep 'ab*c' |
+ (ERE) | 1 oder mehr | grep -E '[0-9]+' |
| (ERE) | oder | grep -E 'error|warn' |
[...] | ein Zeichen aus der Menge | grep '[Ee]rror' |
# Zeilen mit Fehlern oder Warnungen
grep -E "ERROR|WARN" app.log
# Nur IP-Adressen aus dem Log, eine pro Zeile (-o gibt nur den Treffer aus)
grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log
grep -P: einen Wert zwischen bekannten Teilen herausholen
GNU grep kennt die Option -P für Perl-artige reguläre Ausdrücke. Damit stehen \K („alles bisher Passende vergessen“) und Lookahead zur Verfügung, sodass Sie nur den Wert ausgeben:
$ echo 'user_id=4821 status=ok' | grep -oP 'user_id=\K[0-9]+'
4821
$ grep -oP '"version":\s*"\K[^"]+' package.json
2.4.1
Die Option -P gibt es nicht in jeder grep-Version (zum Beispiel fehlt sie im BSD-grep unter macOS). In portablen Skripten sollten Sie deshalb sed oder awk verwenden.
grep -q in Skriptbedingungen
grep -q gibt nichts aus und liefert nur den Exitcode zurück: 0 bei einem Treffer, 1 ohne Treffer. So lässt sich die Prüfung direkt in if schreiben:
if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config; then
echo "Root-Anmeldung ist deaktiviert"
fi
Das ist kürzer, als die Ausgabe in eine Variable zu speichern und auf Leere zu prüfen. Außerdem stoppt grep beim ersten Treffer.
sed: Text ersetzen und löschen
Ersetzen mit dem Befehl s
Der wichtigste sed-Befehl ist s/Muster/Ersatz/Optionen. Ohne die Option g wird pro Zeile nur der erste Treffer ersetzt.
# Text mit Ersetzung ausgeben (die Datei bleibt unverändert)
sed 's/foo/bar/' datei.txt
# Alle Vorkommen in der Zeile ersetzen
sed 's/foo/bar/g' datei.txt
# Ohne Beachtung der Groß- und Kleinschreibung (GNU sed)
sed 's/error/ERROR/gI' app.log
# Anderes Trennzeichen, wenn der Text Schrägstriche enthält
sed 's|/var/www|/srv/www|g' nginx.conf
sed -i: Ersetzen direkt in der Datei
Die Option -i schreibt das Ergebnis zurück in die Datei. Damit das Original nicht verloren geht, geben Sie ein Suffix für die Sicherungskopie an:
# Legt config.ini.bak an und ändert config.ini
sed -i.bak 's/^debug=true/debug=false/' config.ini
# Ersetzen in allen .conf-Dateien eines Verzeichnisses
find /etc/myapp -name "*.conf" -exec sed -i 's/old-host/new-host/g' {} +
Starten Sie eine Massenänderung zuerst ohne -i und prüfen Sie die Ausgabe. Unter macOS (BSD sed) braucht -i ein Argument: sed -i '' 's/a/b/' datei.
Zeilen nach Nummer und nach Muster
# Zeilen 10 bis 20 anzeigen (-n schaltet die Autoausgabe ab, p gibt aus)
sed -n '10,20p' datei.txt
# Zeile 5 löschen
sed '5d' datei.txt
# Letzte Zeile löschen
sed '$d' datei.txt
# Leerzeilen und Kommentare löschen
sed -e '/^$/d' -e '/^#/d' nginx.conf
# Nur in Zeilen mit „listen“ ersetzen
sed '/listen/s/80/8080/' nginx.conf
# Zeile nach einem Treffer einfügen (GNU sed)
sed '/^\[mysqld\]/a max_connections = 500' my.cnf
Rückverweise und &
Einen Teil des Musters in Klammern können Sie im Ersatz über \1, \2 wieder einsetzen. Das Zeichen & steht für den gesamten Treffer.
# Vor- und Nachname tauschen (ERE mit -E)
$ echo "Müller Anna" | sed -E 's/(\S+) (\S+)/\2 \1/'
Anna Müller
# Alle Zahlen in eckige Klammern setzen
$ echo "port 8080, timeout 30" | sed -E 's/[0-9]+/[&]/g'
port [8080], timeout [30]
# Datum 2026-10-14 in 14.10.2026 umwandeln
$ echo 2026-10-14 | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/'
14.10.2026
awk: Spalten, Bedingungen und Berechnungen
Eine bestimmte Spalte ausgeben
awk zerlegt jede Zeile an Leerzeichen und Tabulatoren in Felder: $1 ist das erste Feld, $2 das zweite, $NF das letzte und $0 die ganze Zeile.
# IP-Adressen aus dem nginx-Log (erste Spalte)
awk '{print $1}' /var/log/nginx/access.log
# Benutzername und Shell aus /etc/passwd (Trennzeichen ist der Doppelpunkt)
awk -F: '{print $1, $7}' /etc/passwd
# Letzte Spalte
df -h | awk '{print $NF}'
# Eigenes Trennzeichen bei der Ausgabe
awk -F: -v OFS=';' '{print $1, $3}' /etc/passwd
Bedingungen: nur passende Zeilen ausgeben
Vor den Block in geschweiften Klammern können Sie eine Bedingung setzen. awk führt die Aktion dann nur für passende Zeilen aus.
# Benutzer mit einer UID ab 1000 (normale Benutzer, keine Systemkonten)
awk -F: '$3 >= 1000 {print $1}' /etc/passwd
# Anfragen mit Antwortcode 500 und höher (9. Feld im combined-Format)
awk '$9 >= 500' access.log
# Zeilen, in denen die 6. Spalte zum regulären Ausdruck passt
awk '$6 ~ /POST/' access.log
# Dateien größer als 100 MB aus der Ausgabe von ls -l
ls -l | awk '$5 > 100*1024*1024 {print $9}'
BEGIN, END und NR: awk als kleines Programm
Der Block BEGIN läuft vor dem Lesen der ersten Zeile, END nach der letzten. NR enthält die Nummer der aktuellen Zeile, im END-Block ihre Gesamtzahl.
# Summe der Antwortgrößen (10. Feld) in Megabyte
awk '{sum += $10} END {printf "%.1f MB\n", sum/1024/1024}' access.log
# Mittlere Antwortzeit aus der letzten Spalte
awk '{s += $NF} END {if (NR) print s/NR}' timings.log
# Kopfzeile einer CSV-Datei überspringen
awk -F, 'NR > 1 {print $2}' users.csv
# Anfragen pro IP zählen: assoziatives Array
awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' access.log | sort -rn | head
Das letzte Beispiel ist ein Klassiker der Log-Analyse: Das Array count mit der IP als Schlüssel ersetzt die Kombination sort | uniq -c und lässt sich leicht erweitern, zum Beispiel auf die Summe des Traffics je Adresse.
Pipelines: grep, sed und awk zusammen
Die eigentliche Stärke zeigt sich in der Kombination. Jedes Werkzeug erledigt seinen Teil, und | reicht das Ergebnis weiter.
Die Top-10-IPs mit Fehlern 5xx
grep ' 50[0-9] ' /var/log/nginx/access.log \
| awk '{print $1}' \
| sort | uniq -c | sort -rn | head -10
412 203.0.113.45
118 198.51.100.7
36 192.0.2.19
Hier filtert grep die Zeilen grob vor, awk schneidet das Feld aus, und sort | uniq -c zählt die Wiederholungen. Dasselbe geht auch mit awk allein: awk '$9 ~ /^5/ {c[$1]++} END {for (i in c) print c[i], i}' access.log | sort -rn | head. Das ist genauer, weil die Spalte mit dem Antwortcode gezielt geprüft wird.
Welche URLs am häufigsten aufgerufen werden
awk '{print $7}' access.log | sed 's/?.*//' | sort | uniq -c | sort -rn | head
sed schneidet hier den Query-Teil ab, damit /search?q=a und /search?q=b als dieselbe Seite gezählt werden.
Werte aus einer Konfiguration ohne Kommentare
grep -v '^\s*#' /etc/myapp/app.env | grep '=' | awk -F= '{print $1}'
Fehler in einer bestimmten Stunde
grep '14/Oct/2026:03:' access.log | awk '$9 >= 500 {print $4, $7, $9}'
Typische Fehler
- Doppelte statt einfache Anführungszeichen bei awk. Bei
awk "{print $1}"ersetzt die Shell das$1schon vor dem Start von awk durch ihre eigene Variable. Schreiben Sie awk-Programme und sed-Ausdrücke in einfache Anführungszeichen. - Das
gbei sed vergessen. Ohne es wird nur der erste Treffer pro Zeile ersetzt, die übrigen bleiben stehen. sed -iohne Prüfung. Ein falscher regulärer Ausdruck verdirbt die Datei stillschweigend. Prüfen Sie zuerst ohne-ioder nutzen Sie-i.bak.+und|funktionieren in grep nicht. Das ist die erweiterte Syntax: Sie brauchengrep -E(odersed -E).- Der Punkt im Muster.
grep 192.168.1.1findet auch192x168y1z1, denn der Punkt steht für „ein beliebiges Zeichen“. Nutzen Siegrep -Foder maskieren Sie mit\.. - Leerzeichen in Spalten. Kann ein Feld Leerzeichen enthalten (CSV, Pfade), legen Sie das Trennzeichen ausdrücklich fest:
awk -F,oderawk -F'\t'. - Überflüssiges cat.
cat datei | grep xfunktioniert, abergrep x dateiist kürzer und startet keinen zusätzlichen Prozess.
Womit sich grep, sed und awk ersetzen lassen
Für JSON sind diese Werkzeuge unbequem: Die Struktur analysiert man besser mit jq (jq '.items[] | select(.status=="active") | .name'), YAML mit yq. Für schnelle rekursive Suche in großen Projekten wird oft ripgrep (Befehl rg) genutzt, das standardmäßig die .gitignore beachtet. Wer die Perl-Syntax bevorzugt, ersetzt sed und awk mit perl -pe 's/a/b/g' und perl -lane 'print $F[0]' in einer Zeile. grep, sed und awk sind aber auf praktisch jedem Server ohne Installation vorhanden, deshalb sollten Sie sie zuerst beherrschen.
Fazit
grep sucht Zeilen, sed verändert sie, awk arbeitet mit Spalten und zählt. Merken Sie sich den Grundbestand: grep -rniE sowie -A/-B/-C, sed 's/.../.../g' mit -i.bak und -n 'Np', awk -F mit $1, $NF, Bedingungen und dem Block END. Aus diesen Bausteinen entsteht fast jede Log-Auswertung. Diese grep sed awk beispiele werden zusammen mit find, jq und curl im Linux-Kurs in der Lektion zur Textverarbeitung im Terminal praktisch durchgespielt.
Häufige Fragen
Worin unterscheidet sich grep von egrep?
egrep ist ein veralteter Alias für grep -E (erweiterte reguläre Ausdrücke). Aktuelle Versionen von GNU grep geben beim Aufruf von egrep eine Warnung aus, schreiben Sie daher grep -E.
Wie finde ich Text in allen Dateien eines Verzeichnisses?
Verwenden Sie grep -rn "Text" /pfad: -r sucht rekursiv, -n zeigt die Zeilennummer. Um die Dateitypen einzuschränken, ergänzen Sie --include="*.php".
Wie ersetze ich Text in vielen Dateien auf einmal?
Verbinden Sie Suche und sed: grep -rl "alt" . | xargs sed -i 's/alt/neu/g'. Machen Sie vorher einen Commit oder eine Sicherungskopie.
Wie gebe ich in awk mehrere Spalten durch Tabulatoren getrennt aus?
Legen Sie das Ausgabe-Trennzeichen fest: awk -v OFS='\t' '{print $1, $3}' datei. Ohne OFS werden Felder bei der Ausgabe durch ein Leerzeichen getrennt.
Wie entferne ich mit sed Leerzeichen am Zeilenende?
Der Befehl sed -i 's/[[:space:]]*$//' datei entfernt in allen Zeilen der Datei abschließende Leerzeichen und Tabulatoren.
Dieses Thema wird im Kurs „Linux: с нуля до уверенного администрирования“ ausführlich mit Praxis behandelt.
Zum Kurs