Ich weiß, dass ich dieses Problem auf verschiedene Arten lösen kann, aber ich frage mich, ob es eine Möglichkeit gibt, es nur mit Bash-Einbauten zu tun, und wenn nicht, wie es am effizientesten geht.
Ich habe eine Datei mit Inhalten wie
AAA
B C DDD
FOO BAR
womit ich nur meine, dass es mehrere Zeilen hat und jede Zeile Leerzeichen haben kann oder nicht. Ich möchte einen Befehl wie
ausführencmd AAA "B C DDD" "FOO BAR"
Wenn ich cmd $(< file)
verwende Ich bekomme
cmd AAA B C DDD FOO BAR
und wenn ich cmd "$(< file)"
verwende Ich bekomme
cmd "AAA B C DDD FOO BAR"
Wie bekomme ich jede Zeile mit genau einem Parameter behandelt?
Akzeptierte Antwort:
Portabel:
set -f # turn off globbing
IFS='
' # split at newlines only
cmd $(cat <file)
unset IFS
set +f
Oder verwenden Sie eine Subshell, um das IFS
zu erstellen und Option ändert lokal:
( set -f; IFS='
'; exec cmd $(cat <file) )
Die Shell führt eine Feldaufteilung und Dateinamengenerierung für das Ergebnis einer Variablen- oder Befehlsersetzung durch, die nicht in doppelten Anführungszeichen steht. Sie müssen also die Generierung von Dateinamen mit set -f
ausschalten , und konfigurieren Sie die Feldaufteilung mit IFS
nur Zeilenumbrüche getrennte Felder zu machen.
Mit bash- oder ksh-Konstrukten ist nicht viel zu gewinnen. Sie können IFS
erstellen lokal für eine Funktion, aber nicht set -f
.
In bash oder ksh93 können Sie die Felder in einem Array speichern, wenn Sie sie an mehrere Befehle übergeben müssen. Sie müssen die Erweiterung zum Zeitpunkt des Aufbaus des Arrays steuern. Dann "${a[@]}"
erweitert sich auf die Elemente des Arrays, eines pro Wort.
set -f; IFS=$'n'
a=($(cat <file))
set +f; unset IFS
cmd "${a[@]}"