Zum Inhalt springen
Bash Anfรคnger 35 min

Pipes, Redirects & Text-Tools

Die Unix-Philosophie in Aktion: Pipes, Redirects, grep, sed, awk, cut und wie du maechtige Pipelines baust.

Aktualisiert:
Inhaltsverzeichnis

Pipes, Redirects & Text-Tools

Das hier ist der Kern der Bash-Produktivitaet. Pipes und die klassischen Unix-Tools verwandeln dich von jemandem, der Befehle eintippt, in einen, der Pipelines baut.

Standard Streams

Jeder Prozess hat drei Streams:

  • stdin (0) - Standardeingabe
  • stdout (1) - Standardausgabe
  • stderr (2) - Fehlerkanal

Alle drei kannst du umleiten und verbinden.

Redirects

Ausgabe in Datei

ls > liste.txt          # > ueberschreibt
ls >> liste.txt         # >> haengt an

Eingabe aus Datei

sort < namen.txt

Fehler umleiten

./skript.sh 2> fehler.log
./skript.sh > ausgabe.log 2> fehler.log
./skript.sh &> alles.log               # beides gemeinsam (Bash 4+)
./skript.sh > alles.log 2>&1           # klassisch: 2 nach 1 umleiten

/dev/null - der Muelleimer

loudcommand > /dev/null 2>&1        # komplett stumm

Pipes | - die Magie

Eine Pipe verbindet stdout des einen Kommandos mit stdin des naechsten:

ls | grep ".txt"        # nur .txt-Dateien
cat log | wc -l         # Zeilen zaehlen

Der wahre Spass beginnt mit Ketten:

ps aux | grep "python" | awk '{print $2}' | xargs kill

Das:

  1. Listet alle Prozesse
  2. Filtert auf โ€œpythonโ€
  3. Extrahiert die PIDs (zweite Spalte)
  4. Gibt sie an kill

Die wichtigsten Text-Tools

cat - concatenate

cat datei.txt             # anzeigen
cat datei1.txt datei2.txt # mehrere verbinden
cat -n datei.txt          # mit Zeilennummern

Fuer reine Anzeige ist oft less besser (laesst Scrollen).

head und tail

head -n 10 datei         # erste 10 Zeilen
tail -n 10 datei         # letzte 10 Zeilen
tail -f /var/log/syslog  # live mitschreiben

wc - word count

wc datei.txt          # Zeilen, Woerter, Bytes
wc -l datei.txt       # nur Zeilen
wc -w datei.txt       # nur Woerter
ls | wc -l            # Anzahl Dateien im Ordner
grep "fehler" log.txt
grep -i "fehler" log.txt       # case-insensitive
grep -v "info" log.txt         # invertiert (alles ausser "info")
grep -r "TODO" .                # rekursiv
grep -n "fehler" log.txt        # mit Zeilennummern
grep -E "warning|error" log.txt # extended regex

sort und uniq

sort namen.txt
sort -r                       # umgekehrt
sort -n zahlen.txt            # numerisch
sort -u                       # unique (alternative)

sort datei | uniq              # Duplikate entfernen
sort datei | uniq -c           # Zaehlen
sort datei | uniq -c | sort -rn  # Haeufigkeit sortiert

cut - Spalten ausschneiden

cut -d',' -f1 daten.csv       # erste Spalte (Trennzeichen Komma)
cut -d':' -f1 /etc/passwd     # Usernames
cut -c1-5 datei.txt           # Zeichen 1-5

tr - Zeichen-Translation

echo "hallo" | tr 'a-z' 'A-Z'        # "HALLO"
echo "a b c" | tr ' ' '\n'           # jedes Wort in neue Zeile
echo "hello" | tr -d 'l'             # "heo" (entfernen)

sed - stream editor

Substitution (der haeufigste Anwendungsfall):

sed 's/alt/neu/' datei.txt           # ersetze erstes "alt" pro Zeile
sed 's/alt/neu/g' datei.txt          # alle Vorkommen
sed -i 's/alt/neu/g' datei.txt       # in-place (Datei selbst aendern)

awk - Text-verarbeitung

awk ist eine Mini-Sprache, die zeilenweise arbeitet:

awk '{print $1}' datei.txt           # erste Spalte
awk '{print $1, $3}' datei.txt       # erste und dritte
awk -F',' '{print $2}' daten.csv     # mit Trennzeichen

awk '$3 > 100' daten.txt             # Zeilen, wo Spalte 3 > 100

awk '{sum += $1} END {print sum}' zahlen.txt   # Summe

$0 ist die ganze Zeile, $1, $2, โ€ฆ die Spalten.

find - Dateien finden

find . -name "*.log"                      # alle .log-Dateien
find . -type f                             # nur Dateien
find . -type d                             # nur Ordner
find . -mtime -7                           # die letzten 7 Tage geaendert
find . -size +10M                          # groesser als 10 MB
find . -name "*.tmp" -delete               # finden und loeschen
find . -name "*.jpg" -exec mv {} bilder/ \;

xargs - Liste an Kommandos

ls *.log | xargs rm                        # alle .log loeschen
find . -name "*.tmp" | xargs rm

echo "abc def" | xargs -n 1                # 1 pro Zeile

tee - Ausgabe teilen

Wenn du Ausgabe gleichzeitig in Datei und auf dem Bildschirm haben willst:

./script.sh | tee log.txt
./script.sh | tee -a log.txt     # anhaengen statt ueberschreiben

Process Substitution <(...)

Eine Pipeline wird wie eine Datei behandelt:

diff <(sort datei1) <(sort datei2)

# statt mit Zwischendateien:
sort datei1 > s1
sort datei2 > s2
diff s1 s2

Elegant.

Command Substitution $(...)

Ergebnis eines Kommandos als String:

echo "Heute: $(date +%Y-%m-%d)"
DATEIEN=$(ls -1 *.txt)

Backgrounding

long_command &               # im Hintergrund
jobs                          # alle Jobs anzeigen
fg %1                         # Job 1 in den Vordergrund
bg %1                         # zurueck in Hintergrund
kill %1                       # Job 1 beenden

Praktische Pipeline-Beispiele

Top 10 haeufigster Anfragen

awk '{print $7}' zugriff.log | sort | uniq -c | sort -rn | head -10

Finde alle grosse Log-Files

find /var/log -type f -size +100M -exec ls -lh {} \;

Fehler der letzten Stunde

grep "$(date -d '1 hour ago' '+%Y-%m-%d %H:')" /var/log/syslog | grep -i error

Count of lines per file type

find . -name "*.py" | xargs wc -l | sort -n

Live-Monitoring

tail -f /var/log/syslog | grep --line-buffered "error"

Das --line-buffered sorgt dafuer, dass grep sofort ausgibt, nicht buffered.

Namen aus CSV extrahieren

cut -d',' -f1 daten.csv | sort -u

Ports und Prozesse

lsof -i -P -n | grep LISTEN | awk '{print $1, $9}' | sort -u

Ein komplettes Mini-Programm

#!/usr/bin/env bash
set -euo pipefail

# Analysiere zugriffs-Logs

LOG="${1:-/var/log/nginx/access.log}"

if [[ ! -f "$LOG" ]]; then
  echo "Log nicht gefunden: $LOG" >&2
  exit 1
fi

echo "== Top 10 IPs =="
awk '{print $1}' "$LOG" | sort | uniq -c | sort -rn | head -10

echo
echo "== Top 10 Pfade =="
awk '{print $7}' "$LOG" | sort | uniq -c | sort -rn | head -10

echo
echo "== Status Codes =="
awk '{print $9}' "$LOG" | sort | uniq -c | sort -rn

echo
echo "== Fehler (4xx, 5xx) =="
awk '$9 ~ /^[45]/' "$LOG" | wc -l

echo
echo "== Fehler-Pfade =="
awk '$9 ~ /^[45]/ {print $7}' "$LOG" | sort | uniq -c | sort -rn | head -10

In 30 Zeilen hast du ein komplettes Log-Analyse-Tool.

Zusammenfassung

  • Streams: stdin (0), stdout (1), stderr (2) - alle umleitbar
  • > / >> / < fuer Dateien, 2>&1 fuer stderr-Umleitung
  • Pipe | verbindet Ausgabe zu Eingabe
  • Klassische Tools: grep, sort, uniq, cut, awk, sed, find, xargs, tee
  • Process Substitution <(...) fuer Pipelines als Datei
  • Command Substitution $(...) zum Ergebnis-Einfangen

Damit hast du das Fundament fuer produktives Bash-Scripting. Im weiteren Kurs vertiefen wir Arrays, Traps, Signal-Handling und echte Produktions-Skripte.

Zurรผck zum Bash Kurs