
Inhalt der Datei.txt (keine Besonderheiten, Textdatei gemäß POSIX-Definition)
iguana
gecko
anole
Beispielskript:
#!/bin/sh
string="$(cat file.txt)"
printf '%s' "$string"
Beispielausgabe:
[coolguy@somemachine ~]$ ./script.sh
iguana
gecko
anole[coolguy@somemachine ~]$
Was ist mit der letzten neuen Zeile passiert? Warum bleiben alle Zeilen außer der letzten erhalten? Es scheint, als müssten wir Echo nicht verwenden, um eine neue Zeile hinzuzufügen, wenn bereits eine vorhanden sein sollte.
Antwort1
Es ist nicht das Drucken, sondern die Befehlsersetzung, die das bewirkt. Es ist so definiert, dass es das tut. Von derPOSIX-Beschreibung:
Die Shell soll die Befehlsersetzung erweitern, indem sie den Befehl in einer Subshell-Umgebung ausführt und die Befehlsersetzung durch die Standardausgabe des Befehls ersetzt.Entfernen von Sequenzen aus einem oder mehreren {newline}-Zeichen am Ende der Ersetzung.
Beachten Sie, dass es entferntallenachstehende Zeilenumbrüche, nicht nur einer.
In einem recht häufigen Fall würden Sie die Befehlsersetzung verwenden, um eine einzeilige Ausgabe zu erfassen, beispielsweise osrev=$(uname -r)
. Die Dienstprogramme drucken normalerweise eine abschließende neue Zeile, um die Befehlszeile für den Benutzerkomfort zu optimieren. In einem Shell-Skript möchten Sie diese Zeichenfolge jedoch möglicherweise als Teil einer anderen verwenden, beispielsweise eines Dateinamens: filename=blahblah-$osrev.dat
. Und in diesem Fall wäre die abschließende neue Zeile nur ein Ärgernis.
Und natürlich echo
fügt ein Plain-Befehl in jedem Fall eine abschließende neue Zeile hinzu.
Wenn Sie den Inhalt der Datei unverändert in der Variablen haben möchten, besteht die übliche Problemumgehung darin, bei der Befehlsersetzung ein zusätzliches Zeichen hinzuzufügen und dieses später zu entfernen:
printf "foo\nbar\n\n" > file
string=$(cat file; echo x)
string=${string%x}
printf '%q\n' "$string"
Das Ergebnis ist eine Ausgabe $'foo\nbar\n\n'
, bei der beide nachstehenden Zeilenumbrüche angezeigt werden.
Abhängig davon, was Sie mit den Daten vorhaben, gibt es möglicherweise andere Möglichkeiten. Beispielsweise eine while read
Schleife oder die von Bash mapfile
, wenn Sie die Datei Zeile für Zeile verarbeiten möchten.