In Bash-Skripten ist das zeilenweise Lesen von Dateien eine grundlegende Technik. Mit einer while-Schleife und dem read-Befehl lassen sich Textdateien Zeile für Zeile verarbeiten.
Syntax
Die Standardmethode zum zeilenweisen Lesen einer Datei:
while IFS= read -r zeile; do
printf '%s\n' "$zeile"
done < eingabe.txt
Erklärung der Bestandteile:
IFS=setzt das interne Feldtrennzeichen auf leer und verhindert damit das Entfernen von führenden und nachfolgenden Leerzeichen.-rdeaktiviert die Interpretation von Backslashes als Escape-Zeichen.zeileist die Variable, die den Inhalt jeder Zeile aufnimmt.< eingabe.txtleitet die Datei in die Schleife um.
Als Einzeiler sieht das so aus:
while IFS= read -r zeile; do printf '%s\n' "$zeile"; done < eingabe.txt
Praktische Beispiele
Einfaches Auslesen einer Datei
Angenommen, eine Datei distros.txt enthält Distributionen mit ihren Paketmanagern:
Ubuntu,apt
Debian,apt
CentOS,yum
Arch Linux,pacman
Fedora,dnf
So liest du die Datei zeilenweise:
while IFS= read -r zeile; do
printf '%s\n' "$zeile"
done < distros.txt
Zeilen filtern
Mit einer if-Abfrage kannst du nur bestimmte Zeilen ausgeben. Dieses Beispiel zeigt nur Distributionen mit apt:
while IFS= read -r zeile; do
if [[ "$zeile" == *"apt"* ]]; then
printf '%s\n' "$zeile"
fi
done < distros.txt
Ausgabe:
Ubuntu,apt
Debian,apt
Zeilen in Felder aufteilen
Mit IFS und mehreren Variablen teilst du jede Zeile in separate Felder auf. Bei einer CSV-Datei mit Komma als Trennzeichen:
while IFS=, read -r distro pm; do
printf '%s verwendet %s\n' "$distro" "$pm"
done < distros.txt
Ausgabe:
Ubuntu verwendet apt
Debian verwendet apt
CentOS verwendet yum
Arch Linux verwendet pacman
Fedora verwendet dnf
Das erste Feld landet in distro, alles nach dem Komma in pm. Bei mehr Feldern als Variablen werden die restlichen Felder der letzten Variable zugewiesen.
Alternative Methoden
Prozess-Substitution
Die Ausgabe eines Befehls lässt sich wie eine Datei behandeln:
while IFS= read -r zeile; do
printf '%s\n' "$zeile"
done < <(cat eingabe.txt)
Diese Variante ist nützlich, wenn du die Ausgabe eines Befehls statt einer Datei verarbeiten willst.
Here String
Mit einem Here String übergibst du den Inhalt einer Variable oder Befehlsausgabe:
while IFS= read -r zeile; do
printf '%s\n' "$zeile"
done <<< "$(cat eingabe.txt)"
Dateideskriptor
Ein expliziter Dateideskriptor gibt dir mehr Kontrolle, etwa wenn du innerhalb der Schleife von der Standardeingabe lesen musst:
while IFS= read -r -u 9 zeile; do
printf '%s\n' "$zeile"
done 9< eingabe.txt
Verwende Dateideskriptoren zwischen 4 und 9, um Konflikte mit den reservierten Deskriptoren 0-3 zu vermeiden.
printf statt echo
Die Beispiele verwenden printf statt echo. Der Grund: echo interpretiert bestimmte Zeichenfolgen als Optionen. Enthalt eine Zeile beispielsweise -e oder -n, verhalt sich echo unerwartet. printf hat dieses Problem nicht.
Zusammenfassung
Mit while IFS= read -r liest du Dateien zeilenweise in Bash. Die Kombination aus leerem IFS und der Option -r stellt sicher, dass Zeilen unverändert verarbeitet werden. Für komplexere Aufgaben kannst du Zeilen in Felder aufteilen oder alternative Eingabemethoden wie Prozess-Substitution verwenden.