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.
  • -r deaktiviert die Interpretation von Backslashes als Escape-Zeichen.
  • zeile ist die Variable, die den Inhalt jeder Zeile aufnimmt.
  • < eingabe.txt leitet 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.