Nehmen wir an, Sie haben diese Datei:
$ cat /tmp/test.txt
Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR
Es gibt vier Elemente, die die Bedeutung der Dateiausgabe, die von vielen Bash-Lösungen gelesen wird, verändern:
- Die leere Zeile 4;
- Führende oder nachgestellte Leerzeichen in zwei Zeilen;
- Beibehaltung der Bedeutung der einzelnen Zeilen (d.h. jede Zeile ist ein Datensatz);
- Die Zeile 6 wurde nicht mit einem CR abgeschlossen.
Wenn Sie die Textdatei zeilenweise mit Leerzeilen und abschließenden Zeilen ohne CR abfragen wollen, müssen Sie eine while-Schleife verwenden und einen alternativen Test für die letzte Zeile vorsehen.
Hier sind die Methoden, die die Datei verändern können (im Vergleich zu dem, was cat
zurück):
1) Streichen Sie die letzte Zeile und die führenden und nachfolgenden Leerzeichen:
$ while read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
(Wenn Sie while IFS= read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
stattdessen bleiben die vor- und nachgestellten Leerzeichen erhalten, aber die letzte Zeile geht verloren, wenn sie nicht mit CR abgeschlossen wird)
2) Verwendung der Prozess-Substitution mit cat
liest die gesamte Datei in einem Zug und verliert die Bedeutung der einzelnen Zeilen:
$ for p in "$(cat /tmp/test.txt)"; do printf "%s\n" "'$p'"; done
'Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR'
(Wenn Sie die "
von $(cat /tmp/test.txt)
Sie lesen die Datei Wort für Wort und nicht in einem Zug. Wahrscheinlich auch nicht das, was beabsichtigt ist...)
Die robusteste und einfachste Methode, eine Datei zeilenweise zu lesen und alle Abstände beizubehalten, ist:
$ while IFS= read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
' Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space '
'Line 6 has no ending CR'
Wenn Sie führende und handelnde Leerzeichen entfernen möchten, entfernen Sie die IFS=
Teil:
$ while read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
'Line 6 has no ending CR'
(Eine Textdatei ohne abschließende \n
ist zwar weit verbreitet, gilt aber unter POSIX als fehlerhaft. Wenn Sie sich auf die nachgestellten \n
brauchen Sie nicht || [[ -n $line ]]
im while
Schleife.)
Mehr auf der BASH-FAQ