Angenommen, 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 von vielen Bash-Lösungen gelesenen Dateiausgabe ändern:
- Die leere Zeile 4;
- Führende oder nachfolgende Leerzeichen in zwei Zeilen;
- Beibehaltung der Bedeutung einzelner Zeilen (dh jede Zeile ist ein Datensatz);
- Die Leitung 6 endete nicht mit einem CR.
Wenn Sie die Textdatei zeilenweise einschließlich Leerzeilen und Abschlusszeilen ohne CR verwenden möchten, müssen Sie eine while-Schleife verwenden und einen alternativen Test für die letzte Zeile durchführen.
Hier sind die Methoden, mit denen die Datei geändert werden kann (im Vergleich zu den cat
zurückgegebenen):
1) Verlieren 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 dies while IFS= read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
stattdessen tun, behalten Sie die führenden und nachfolgenden Leerzeichen bei, verlieren jedoch die letzte Zeile, wenn sie nicht mit CR abgeschlossen wird.)
2) Wenn Sie die Prozesssubstitution mit cat
Willen verwenden, wird die gesamte Datei in einem Zug gelesen und die Bedeutung einzelner Zeilen verloren:
$ 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 das Entfernen "
von $(cat /tmp/test.txt)
Ihnen lesen Sie die Datei Wort für Wort , anstatt einem Zug. Auch wahrscheinlich nicht , was beabsichtigt ist ...)
Der robusteste und einfachste Weg, eine Datei Zeile für Zeile 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 das 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 Terminierung \n
wird unter POSIX als fehlerhaft angesehen , obwohl sie ziemlich häufig vorkommt. Wenn Sie sich auf das Trailing verlassen können, das \n
Sie || [[ -n $line ]]
in der while
Schleife nicht benötigen .)
Mehr in den BASH FAQ