it-swarm.com.de

Wie verwende ich die Zeilen einer Datei als Argumente eines Befehls?

Angenommen, ich habe eine Datei foo.txt Angabe von N Argumenten

arg1
arg2
...
argN

was muss ich an den Befehl übergeben my_command

Wie verwende ich die Zeilen einer Datei als Argumente eines Befehls?

125
Yoo

Wenn Ihre Shell (unter anderem) bash ist, ist eine Verknüpfung für $(cat afile)$(< afile), also schreiben Sie:

mycommand "$(< file.txt)"

Dokumentiert auf der bash-Manpage im Abschnitt 'Command Substitution'.

Lass deinen Befehl alternativ von stdin lesen, also: mycommand < file.txt

194
glenn jackman

Wie bereits erwähnt, können Sie die Backticks oder $(cat filename) verwenden.

Was nicht erwähnt wurde, und ich denke, es ist wichtig zu erwähnen, dass Sie daran denken müssen, dass die Shell den Inhalt dieser Datei nach Leerzeichen aufteilt und jedes "Wort", das sie findet, Ihrem Befehl als Argument gibt. Und obwohl Sie möglicherweise ein Befehlszeilenargument in Anführungszeichen setzen können, damit es Leerzeichen, Escape-Sequenzen usw. enthält, kann beim Lesen aus der Datei nicht dasselbe erreicht werden. Zum Beispiel, wenn Ihre Datei enthält:

a "b c" d

die Argumente, die Sie erhalten, sind:

a
"b
c"
d

Wenn Sie jede Zeile als Argument ziehen möchten, verwenden Sie das while/read/do-Konstrukt:

while read i ; do command_name $i ; done < filename
35
Will

Du machst das mit Backticks:

echo World > file.txt
echo Hello `cat file.txt`
15
Tommy Lacroix
command `< file`

übergibt den Dateiinhalt an den Befehl stdin, entfernt jedoch Zeilenumbrüche, sodass Sie nicht jede Zeile einzeln durchlaufen können. Dafür könnten Sie ein Skript mit einer 'for'-Schleife schreiben:

for i in `cat input_file`; do some_command $i; done
14
Wesley Rice

Wenn Sie dies auf robuste Weise tun möchten, die für jedes mögliche Befehlszeilenargument funktioniert (Werte mit Leerzeichen, Werte mit Zeilenumbrüchen, Werte mit wörtlichen Anführungszeichen, nicht druckbare Werte, Werte mit globalen Zeichen usw.), wird es ein bisschen interessanter.


Um in eine Datei zu schreiben, geben Sie ein Array von Argumenten an:

printf '%s\0' "${arguments[@]}" >file

...ersetzen mit "argument one", "argument two" usw. entsprechend.


So lesen Sie aus dieser Datei und verwenden deren Inhalt (in bash, ksh93 oder einer anderen aktuellen Shell mit Arrays):

declare -a args=()
while IFS='' read -r -d '' item; do
  args+=( "$item" )
done <file
run_your_command "${args[@]}"

Um aus dieser Datei zu lesen und ihren Inhalt zu verwenden (in einer Shell ohne Arrays), beachten Sie, dass dies Ihre lokale Befehlszeilenargumentliste überschreibt und daher am besten innerhalb einer Funktion durchgeführt wird, sodass Sie die Argumente der Funktion überschreiben und nicht die globale Liste):

set --
while IFS='' read -r -d '' item; do
  set -- "[email protected]" "$item"
done <file
run_your_command "[email protected]"

Beachten Sie, dass -d (mit dem ein anderes Trennzeichen für das Zeilenende verwendet werden kann) ist eine Nicht-POSIX-Erweiterung und wird möglicherweise auch von einer Shell ohne Arrays nicht unterstützt. In diesem Fall müssen Sie möglicherweise eine Nicht-Shell-Sprache verwenden, um den durch NUL getrennten Inhalt in eine eval -sichere Form umzuwandeln:

quoted_list() {
  ## Works with either Python 2.x or 3.x
  python -c '
import sys, pipes, shlex
quote = pipes.quote if hasattr(pipes, "quote") else shlex.quote
print(" ".join([quote(s) for s in sys.stdin.read().split("\0")][:-1]))
  '
}

eval "set -- $(quoted_list <file)"
run_your_command "[email protected]"
7
Charles Duffy

So übergebe ich den Inhalt einer Datei als Argument an einen Befehl:

./foo --bar "$(cat ./bar.txt)"
6
chovy

In meiner Bash-Shell wirkte Folgendes wie ein Zauber:

cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'

dabei ist input_file

arg1
arg2
arg3

Wie offensichtlich, können Sie mit jeder Zeile aus input_file mehrere Befehle ausführen, ein netter kleiner Trick, den ich gelernt habe hier .

2
honkaboy