
Beim Schreiben von Bash-Skripten kommt man manchmal in Situationen, in denen man eine Datei Zeile für Zeile lesen muss. Beispielsweise haben Sie möglicherweise eine Textdatei mit Daten, die vom Skript verarbeitet werden sollen.
In diesem Tutorial werden wir besprechen, wie man eine Datei Zeile für Zeile in Bash liest.
Lesen einer Datei Zeile für Zeile Syntax #
Die allgemeinste Syntax zum zeilenweisen Lesen einer Datei lautet wie folgt:
while IFS= read -r line; do
printf '%s\n' "$line"
done < input_file
oder die entsprechende einzeilige Version:
while IFS= read -r line; do printf '%s\n' "$line"; done < input_file
Wie funktioniert es?
Die Eingabedatei (input_file
) ist der Name der Datei, die an die While-Schleife umgeleitet wird. Der read
Der Befehl verarbeitet die Datei Zeile für Zeile und weist jede Zeile der line
zu Variable. Sobald alle Zeilen verarbeitet sind, wird die While-Schleife beendet.
Standardmäßig wird der read
Der Befehl interpretiert den Backslash als Escape-Zeichen und entfernt alle führenden und abschließenden Leerzeichen, was manchmal zu unerwartetem Verhalten führen kann. Um das Backslash-Escape zu deaktivieren, rufen wir den Befehl mit -r
auf Option und zum Deaktivieren des Trimmens wird der interne Feldtrenner (IFS
) gelöscht.
Wir verwenden [printf
] statt echo
um den Code portabler zu machen und unerwünschtes Verhalten zu vermeiden. Wenn die Zeile beispielsweise Werte wie „-e“ enthält, wird sie als Echooption behandelt.
Beispiele zum zeilenweisen Lesen einer Datei #
Schauen wir uns das folgende Beispiel an. Angenommen, wir haben eine Datei namens distros.txt
enthält eine Liste einiger der beliebtesten Linux-Distributionen und ihrer Paketmanager, getrennt durch Kommas (,
):
Ubuntu,apt
Debian,apt
CentOS,yum
Arch Linux,pacman
Fedora,dnf
Um die Datei Zeile für Zeile zu lesen, würden Sie den folgenden Code in Ihrem Terminal ausführen:
while IFS= read -r line; do
printf '%s\n' "$line"
done < distros.txt
Der Code liest die Datei zeilenweise, weist jede Zeile einer Variablen zu und gibt sie aus. Grundsätzlich würden Sie die gleiche Ausgabe sehen, als würden Sie den Dateiinhalt mit dem cat
anzeigen Befehl.
Was ist, wenn Sie nur die Distributionen drucken möchten, die apt verwenden? Eine Möglichkeit wäre, den if
zu verwenden -Anweisung und prüfen Sie, ob die Zeile den apt-Teilstring enthält:
while IFS= read -r line; do
if [[ "$line" == *"apt"* ]]; then
printf '%s\n' "$line"
fi
done < distros.txt
Ubuntu,apt
Debian,apt
Beim zeilenweisen Lesen einer Datei können Sie auch mehr als eine Variable an read
übergeben Befehl, der die Zeile basierend auf IFS
in Felder aufteilt . Das erste Feld wird der ersten Variablen zugewiesen, das zweite der zweiten Variablen und so weiter. Wenn mehr Felder als Variablen vorhanden sind, werden die übrig gebliebenen Felder der letzten Variablen zugewiesen.
Im folgenden Beispiel setzen wir IFS
zu einem Komma (,
) und übergeben Sie zwei Variablen distro
und pm
zum read
Befehl. Alles vom Anfang der Zeile bis zum ersten Komma wird der ersten Variablen zugewiesen (distro
), und der Rest der Zeile wird der zweiten Variablen zugewiesen (pm
):
while IFS=, read -r distro pm; do
printf '%s is the package manager for %s\n' "$pm" "$distro"
done < distros.txt
apt is the package manager for Ubuntu
apt is the package manager for Debian
yum is the package manager for CentOS
pacman is the package manager for Arch Linux
dnf is the package manager for Fedora
Alternative Dateilesemethoden #
Eine Prozesssubstitution verwenden #
Die Prozessersetzung ist eine Funktion, mit der Sie die Ausgabe des Befehls als Datei verwenden können:
while IFS= read -r line; do
printf '%s\n' "$line"
done < <(cat input_file )
Hier-Zeichenfolge verwenden #
Here String ist eine Variante von Here document. Die Zeichenfolge (cat input_file )
behält die Zeilenumbrüche:
while IFS= read -r line; do
printf '%s\n' "$line"
done <<< $(cat input_file )
Using File descriptor #
Sie können die Eingabe für die Schleife auch mit einem Dateideskriptor bereitstellen:
while IFS= read -r -u9 line; do
printf '%s\n' "$line"
done 9< input_file
Wenn Sie mit Dateideskriptoren arbeiten, verwenden Sie eine Zahl zwischen 4 und 9, um Konflikte mit Shell-internen Dateideskriptoren zu vermeiden.
Schlussfolgerung #
In Bash können wir eine Datei Zeile für Zeile mit einer While-Schleife und dem read
lesen Befehl.
Wenn Sie Fragen oder Feedback haben, können Sie gerne einen Kommentar hinterlassen.