Je sais que, étant donné l="a b c"
,
echo $l | xargs ls
les rendements
ls a b c
Quelle construction donne
mycommand -f a -f b -f c
Je sais que, étant donné l="a b c"
,
echo $l | xargs ls
les rendements
ls a b c
Quelle construction donne
mycommand -f a -f b -f c
Réponses:
Une façon de le faire:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
Cela suppose a
, b
et c
ne contient pas de blancs, de nouvelles lignes, de guillemets ou de barres obliques inverses. :)
Avec GNU, findutil
vous pouvez gérer le cas général, mais c'est un peu plus compliqué:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
Vous pouvez remplacer le |
séparateur par un autre caractère, qui ne semble pas a
, b
ou c
.
Edit: Comme le note @MichaelMol , avec une très longue liste d'arguments, il existe un risque de débordement de la longueur maximale des arguments qui peuvent être passés mycommand
. Lorsque cela se produit, le dernier xargs
divisera la liste et exécutera une autre copie de mycommand
, et il y a un risque qu'elle ne soit pas terminée -f
. Si vous vous inquiétez de cette situation, vous pouvez remplacer le dernier xargs -0
ci-dessus par quelque chose comme ceci:
... | xargs -x -0 mycommand
Cela ne résoudra pas le problème, mais interrompra l'exécution mycommand
lorsque la liste des arguments devient trop longue.
mycommand
. Vous pouvez toujours ajouter -x
au dernier xargs
.
xargs
du tout, et de l'utiliser uniquement find
si elle peut être utilisée. Cette solution est dangereuse; vous devez au moins avertir du cas d'échec dans votre réponse.
find
serait une meilleure solution générale, en particulier lorsque les arguments initiaux ne sont pas des noms de fichiers. :)
-f
et avec un exemple d'outil ls
utilisé pour l'illustration, @ not-a-user traite les noms de fichiers. Et donné find
offre l' -exec
argument, qui vous permet de construire une ligne de commande, ça va. (Tant qu'il mycommand
est permis d'exécuter plus d'une fois. Si ce n'est pas le cas, alors nous avons un autre problème avec l'utilisation d' xargs
ici ...)
Une meilleure façon d'y remédier (OMI) serait:
dans zsh
:
l=(a b c)
mycommand -f$^l
ou en utilisant le zipping de tableau pour que l'argument ne soit pas attaché à l'option:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
De cette façon, cela fonctionne toujours si le l
tableau contient des éléments vides ou des éléments contenant des espaces ou tout autre caractère problématique pour xargs
. Exemple:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>
dans rc
:
l=(a b c)
mycommand -f$l
dans fish
:
set l a b c
mycommand -f$l
(AFAIK, rc
et fish
n'ont pas de fermeture éclair de tableau)
Avec des shells de type Bourne à l'ancienne bash
, vous pouvez toujours le faire (en autorisant toujours n'importe quel caractère dans les éléments du $@
tableau):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done;
mycommand "${args[@]}"
. IDK si c'est plus rapide, mais l'ajout de 2 éléments à un tableau semble être O (n), tandis que votre set
boucle copie et ré-analyse probablement la liste d'arguments accumulée à chaque fois (O (n ^ 2)).
ARG_MAX
et d'avoir un-f
paramètre séparé de son paramètre apparié.