Kurz: Die Stärke der Shell sind die kleinen Textprogramme, die du mit Pipes kombinierst. Wir arbeiten mit einer kleinen Beispieldatei:
Teil des Kurses Bash
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.txtAusgabe:
6 log.txt
2025-03-01 INFO Server gestartet
2025-03-01 ERROR Datenbank nicht erreichbar
2025-03-03 INFO Nutzer tom angemeldetgrep: 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"Ausgabe:
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 LogWeitere 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/=.*//'Ausgabe:
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
yMit 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'Ausgabe:
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.txtAusgabe:
Mia
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ölnNü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 | sortAusgabe:
./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.cPraxisbeispiel: 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,Ausgabe:
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
Übungsaufgabe
Finde in einer Beispiel-Logdatei die 3 häufigsten IP-Adressen (awk, sort, uniq -c, head).
Quiz zur Selbstkontrolle
Welcher Befehl ersetzt Text in jeder Zeile?
- sed ‘s/alt/neu/g’ (richtig)
- grep alt neu
- cut -d alt
- sort alt
Wie zählst du mit Bordmitteln, wie oft jede Zeile vorkommt?
- sort | uniq -c (richtig)
- uniq | sort
- count
- wc -u
Welche awk-Variable enthält die Zeilennummer?
- NR (richtig)
- NF
- FS
- LN
Weiter im Kurs
Zurück: Pipes, Umleitungen und Prozesse
Weiter: Dateisystem, Navigation und Rechte
Alle Kapitel: Bash im Überblick