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
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
Antworten:
Ein Weg, es zu tun:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Dies setzt voraus a, bund centhält keine Leerzeichen, Zeilenumbrüche, Anführungszeichen oder Backslashes. :)
Mit GNU können findutilSie 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, boder 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 xargswird 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 -0durch Folgendes ersetzen :
... | xargs -x -0 mycommand
Dies wird das Problem nicht lösen, aber die Ausführung wird abgebrochen, mycommandwenn die Liste der Argumente zu lang wird.
mycommand. Sie könnten immer -xzum letzten hinzufügen xargs.
xargsund nur zu verwenden, findwenn es verwendet werden kann. Diese Lösung ist gefährlich; Sie sollten in Ihrer Antwort zumindest vor dem Fehlerfall warnen.
findbessere allgemeine Lösung, insbesondere wenn die anfänglichen Argumente keine Dateinamen sind. :)
-fund einem Beispieltool lszur Veranschaulichung mit Dateinamen befasst. Und da findbietet das -execArgument, das Ihnen erlaubt zu konstruieren eine Befehlszeile, es ist in Ordnung. (Solange mycommanderlaubt ist, mehr als einmal auszuführen. Wenn es nicht ist, dann haben wir ein anderes Problem mit der Verwendung von xargshier ...)
Ein besserer Weg, um es anzugehen (IMO) wäre:
in zsh:
l=(a b c)
mycommand -f$^l
oder mit Array-Zipping, damit das Argument nicht an die Option angehängt wird:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
Auf diese Weise funktioniert es immer noch, wenn das lArray leere Elemente oder Elemente enthält, die Leerzeichen oder andere problematische Zeichen für enthalten xargs. Beispiel:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>in rc:
l=(a b c)
mycommand -f$lin fish:
set l a b c
mycommand -f$l(AFAIK rcund fishkein Array-Zippen)
Mit Bourne-ähnlichen Shells im alten Stil bashkönnten Sie immer Folgendes tun (und trotzdem jedes Zeichen in den Elementen des $@Arrays zulassen):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
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 Ihre setSchleife wahrscheinlich jedes Mal die akkumulierte Arg-Liste kopiert und erneut analysiert (O (n ^ 2)).
ARG_MAX, einen-fvon seinem gepaarten Parameter getrennten Wert zu überschreiten und zu haben .