Ich weiß, dass gegeben l="a b c"
,
echo $l | xargs ls
Ausbeuten
ls a b c
Welches Konstrukt ergibt
mycommand -f a -f b -f c
quelle
Ich weiß, dass gegeben l="a b c"
,
echo $l | xargs ls
Ausbeuten
ls a b c
Welches Konstrukt ergibt
mycommand -f a -f b -f c
Ein Weg, es zu tun:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Dies setzt voraus a
, b
und c
enthält keine Leerzeichen, Zeilenumbrüche, Anführungszeichen oder Backslashes. :)
Mit GNU können findutil
Sie den allgemeinen Fall behandeln, aber es ist etwas komplizierter:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Sie können den ersetzen |
Separator mit einem anderen Zeichen, dass nicht angezeigt wird in a
, b
oder c
.
Bearbeiten: Wie @MichaelMol feststellt, besteht bei einer sehr langen Liste von Argumenten die Gefahr, dass die maximale Länge der Argumente, an die übergeben werden kann, überschritten wird mycommand
. In diesem Fall xargs
wird die Liste beim letzten Mal geteilt und eine weitere Kopie von ausgeführt mycommand
. Es besteht die Gefahr, dass die Liste nicht abgeschlossen wird -f
. Wenn Sie sich wegen dieser Situation Sorgen machen, können Sie die letzte xargs -0
durch Folgendes ersetzen :
... | xargs -x -0 mycommand
Dies wird das Problem nicht lösen, aber die Ausführung wird abgebrochen, mycommand
wenn die Liste der Argumente zu lang wird.
ARG_MAX
, einen-f
von seinem gepaarten Parameter getrennten Wert zu überschreiten und zu haben .mycommand
. Sie könnten immer-x
zum letzten hinzufügenxargs
.xargs
und nur zu verwenden,find
wenn es verwendet werden kann. Diese Lösung ist gefährlich; Sie sollten in Ihrer Antwort zumindest vor dem Fehlerfall warnen.find
bessere allgemeine Lösung, insbesondere wenn die anfänglichen Argumente keine Dateinamen sind. :)-f
und einem Beispieltoolls
zur Veranschaulichung mit Dateinamen befasst. Und dafind
bietet das-exec
Argument, das Ihnen erlaubt zu konstruieren eine Befehlszeile, es ist in Ordnung. (Solangemycommand
erlaubt ist, mehr als einmal auszuführen. Wenn es nicht ist, dann haben wir ein anderes Problem mit der Verwendung vonxargs
hier ...)Ein besserer Weg, um es anzugehen (IMO) wäre:
in
zsh
:oder mit Array-Zipping, damit das Argument nicht an die Option angehängt wird:
Auf diese Weise funktioniert es immer noch, wenn das
l
Array leere Elemente oder Elemente enthält, die Leerzeichen oder andere problematische Zeichen für enthaltenxargs
. Beispiel:in
rc
:in
fish
:(AFAIK
rc
undfish
kein Array-Zippen)Mit Bourne-ähnlichen Shells im alten Stil
bash
könnten Sie immer Folgendes tun (und trotzdem jedes Zeichen in den Elementen des$@
Arrays zulassen):quelle
for i; do args+=('-f' "$i");done;
mycommand "${args[@]}"
. IDK, wenn dies schneller ist, aber das Anhängen von 2 Elementen an ein Array wie O (n) erscheint, während Ihreset
Schleife wahrscheinlich jedes Mal die akkumulierte Arg-Liste kopiert und erneut analysiert (O (n ^ 2)).