Die Textwerkzeuge
Die Stärke der Shell sind die kleinen Textprogramme, die du mit Pipes kombinierst. Wir arbeiten mit einer kleinen Beispieldatei:
cat > log.txt <<'EOF'
2025-03-01 INFO Server gestartet
2025-03-01 ERROR Datenbank nicht erreichbar
2025-03-02 INFO Nutzer mia angemeldet
2025-03-02 WARN Speicher knapp
2025-03-03 ERROR Zeitüberschreitung bei /api/data
2025-03-03 INFO Nutzer tom angemeldet
EOF
wc -l log.txt
head -n 2 log.txt
tail -n 1 log.txt6 log.txt 2025-03-01 INFO Server gestartet 2025-03-01 ERROR Datenbank nicht erreichbar 2025-03-03 INFO Nutzer tom angemeldet
grep: suchen
cat > log.txt <<'EOF'
2025-03-01 INFO Server gestartet
2025-03-01 ERROR Datenbank nicht erreichbar
2025-03-02 INFO Nutzer mia angemeldet
2025-03-02 WARN Speicher knapp
2025-03-03 ERROR Zeitüberschreitung bei /api/data
2025-03-03 INFO Nutzer tom angemeldet
EOF
grep ERROR log.txt # Zeilen mit ERROR
grep -c INFO log.txt # zählen
grep -v INFO log.txt # alles außer INFO
grep -i "nutzer" log.txt # Groß-/Kleinschreibung egal
grep -n WARN log.txt # mit Zeilennummer
grep -E "ERROR|WARN" log.txt # erweiterte Regex (oder)
grep -o "Nutzer [a-z]*" log.txt # nur den Treffer
grep -w "mia" log.txt # ganzes Wort
grep -E "^2025-03-0[12]" log.txt | wc -l
grep -A1 "WARN" log.txt # eine Zeile danach
grep -q "ERROR" log.txt && echo "Fehler im Log"2025-03-01 ERROR Datenbank nicht erreichbar 2025-03-03 ERROR Zeitüberschreitung bei /api/data 3 2025-03-01 ERROR Datenbank nicht erreichbar 2025-03-02 WARN Speicher knapp 2025-03-03 ERROR Zeitüberschreitung bei /api/data 2025-03-02 INFO Nutzer mia angemeldet 2025-03-03 INFO Nutzer tom angemeldet 4:2025-03-02 WARN Speicher knapp 2025-03-01 ERROR Datenbank nicht erreichbar 2025-03-02 WARN Speicher knapp 2025-03-03 ERROR Zeitüberschreitung bei /api/data Nutzer mia Nutzer tom 2025-03-02 INFO Nutzer mia angemeldet 4 2025-03-02 WARN Speicher knapp 2025-03-03 ERROR Zeitüberschreitung bei /api/data Fehler im Log
Weitere Optionen: -r (rekursiv in Ordnern), -l (nur Dateinamen), -F (fester Text statt Regex), -P (Perl-Regex, wo verfügbar).
sed: Text umformen
sed (stream editor) bearbeitet Text zeilenweise, am häufigsten mit s/alt/neu/:
echo "Hallo Welt, Hallo Bash" | sed 's/Hallo/Hi/' # erstes pro Zeile
echo "Hallo Welt, Hallo Bash" | sed 's/Hallo/Hi/g' # alle
echo "a/b/c" | sed 's|/|-|g' # anderes Trennzeichen
echo "2025-03-15" | sed -E 's/([0-9]+)-([0-9]+)-([0-9]+)/\3.\2.\1/'
printf "eins\nzwei\ndrei\nvier\n" | sed -n '2,3p' # nur Zeilen 2 bis 3
printf "eins\nzwei\ndrei\n" | sed '/zwei/d' # Zeilen löschen
printf " Text \n" | sed 's/^ *//; s/ *$//' | sed 's/.*/[&]/'
printf "a\nb\n" | sed 's/^/> /'
printf "eins\nzwei\n" | sed '1i Kopfzeile'
printf "x=1\ny=2\n" | sed 's/=.*//'Hi Welt, Hallo Bash Hi Welt, Hi Bash a-b-c 15.03.2025 zwei drei eins drei [Text] > a > b Kopfzeile eins zwei x y
Mit sed -i 's/alt/neu/g' datei änderst du die Datei direkt (zur Sicherheit sed -i.bak ...).
cut, sort, uniq, tr, wc
printf "mia:17:Berlin\ntom:25:Hamburg\nzoe:31:Berlin\n" > leute.txt
cut -d: -f1 leute.txt # Spalte 1
cut -d: -f2,3 leute.txt
cut -c1-3 leute.txt # Zeichen 1 bis 3
sort -t: -k2 -n leute.txt # nach Spalte 2 numerisch
sort -t: -k3 leute.txt | cut -d: -f3 | uniq -c
printf "b\na\nb\nc\na\n" | sort | uniq # Duplikate zusammenfassen
printf "b\na\nb\nc\na\n" | sort | uniq -d # nur Duplikate
printf "b\na\nb\n" | sort -u
echo "Hallo" | tr 'a-z' 'A-Z'
echo "a,b;c" | tr ',;' ' '
echo "aabbcc" | tr -s 'a-c' # Wiederholungen zusammenziehen
echo "geheim123" | tr -d '0-9'
wc -l -w -c <<< "drei kleine Wörter"
paste -sd, <<< $'1\n2\n3'
sort -r <<< $'a\nc\nb'
sort -h <<< $'10K\n2M\n500'
tac <<< $'1\n2\n3'mia
tom
zoe
17:Berlin
25:Hamburg
31:Berlin
mia
tom
zoe
mia:17:Berlin
tom:25:Hamburg
zoe:31:Berlin
2 Berlin
1 Hamburg
a
b
c
a
b
a
b
HALLO
a b c
abc
geheim
1 3 20
1,2,3
c
b
a
500
10K
2M
3
2
1awk: Spalten und Berechnungen
awk liest Zeilen, teilt sie in Felder ($1, $2 ...) und führt Aktionen aus: awk 'Muster { Aktion }'.
printf "Mia 17 Berlin\nTom 25 Hamburg\nZoe 31 Berlin\nBen 9 Köln\n" > p.txt
awk '{ print $1 }' p.txt # erste Spalte
awk '{ print $3, $1 }' p.txt # umsortiert
awk '$2 >= 18 { print $1 " ist volljährig" }' p.txt
awk '$3 == "Berlin"' p.txt
awk '{ summe += $2 } END { print "Summe:", summe, "Mittel:", summe / NR }' p.txt
awk '{ n[$3]++ } END { for (s in n) print s, n[s] }' p.txt | sort
awk 'NR % 2 == 0' p.txt # jede zweite Zeile
awk -F: '{ print $1 }' <<< "root:x:0" # anderes Trennzeichen
awk '{ printf "%-5s|%3d|\n", $1, $2 }' p.txt
awk 'length($1) == 3 && /e/ { print NR": "$0 }' p.txtMia Tom Zoe Ben Berlin Mia Hamburg Tom Berlin Zoe Köln Ben Tom ist volljährig Zoe ist volljährig Mia 17 Berlin Zoe 31 Berlin Summe: 82 Mittel: 20.5 Berlin 2 Hamburg 1 Köln 1 Tom 25 Hamburg Ben 9 Köln root Mia | 17| Tom | 25| Zoe | 31| Ben | 9| 1: Mia 17 Berlin 3: Zoe 31 Berlin 4: Ben 9 Köln
Nützliche awk-Variablen: NR (Zeilennummer), NF (Feldanzahl), $0 (ganze Zeile), FS/OFS (Trennzeichen).
find und xargs
cd "$(mktemp -d)"
mkdir -p src/lib docs
touch src/main.c src/lib/util.c src/lib/util.h docs/readme.md notiz.txt
find . -name "*.c" | sort
find . -type d | sort
find . -type f -name "*.h" -o -name "*.md" | sort
find . -maxdepth 1 -type f
find src -name "*.c" -exec basename {} \; | sort
find . -type f -empty | wc -l
find . -name "*.c" -print0 | xargs -0 -n1 basename | sort./src/lib/util.c ./src/main.c . ./docs ./src ./src/lib ./docs/readme.md ./src/lib/util.h ./notiz.txt main.c util.c 5 main.c util.c
Praxisbeispiel: Log auswerten
cat > log.txt <<'EOF'
2025-03-01 INFO Server gestartet
2025-03-01 ERROR Datenbank nicht erreichbar
2025-03-02 INFO Nutzer mia angemeldet
2025-03-02 WARN Speicher knapp
2025-03-03 ERROR Zeitüberschreitung bei /api/data
2025-03-03 INFO Nutzer tom angemeldet
EOF
echo "Meldungen pro Stufe:"
awk '{ print $2 }' log.txt | sort | uniq -c | sort -rn
echo "Fehler pro Tag:"
grep ERROR log.txt | cut -d' ' -f1 | sort | uniq -c
echo "Angemeldete Nutzer:"
grep -o 'Nutzer [a-z]*' log.txt | cut -d' ' -f2 | paste -sd,Meldungen pro Stufe:
3 INFO
2 ERROR
1 WARN
Fehler pro Tag:
1 2025-03-01
1 2025-03-03
Angemeldete Nutzer:
mia,tomMerke
grepsucht (-i -v -n -c -E -o -r),sedersetzt (s/a/b/g),awkrechnet mit Spaltencut,sort,uniq -c,tr,wc,head,tail,pasteals Bausteinefind ... -exec/xargswenden Befehle auf Dateien an- Pipes kombinieren alles zu kleinen Auswertungen
Aufgabe
Finde in einer Beispiel-Logdatei die 3 häufigsten IP-Adressen (awk, sort, uniq -c, head).