xargs -Je comportement

1

Une variable var contient plusieurs arguments, chacun divisé par une nouvelle ligne.

echo "$var" | xargs -I % echo ABC %
#Results in:
#ABC One
#ABC Two
#ABC Three

Cependant, en omettant -I et le % caractères, je reçois le texte suivant:

echo "$var" | xargs echo ABC
#Results in:
#ABC One Two Three

Une fois que j'ai lu, {} remplacerait l'argument actuel (comme le ferait find), mais cela ne se produit pas. Qu'est-ce que je fais mal?

David Stockinger
la source

Réponses:

3

Le comportement habituel de xargs consiste à coller autant d’arguments que possible sur la ligne de commande de toute commande exécutée, en effectuant une itération jusqu’à ce que tous les éléments soient traités. Utilisé de cette manière, il résout le problème des limites de longueur de ligne de commande.

Mais quand vous spécifiez le -I option, il exécute la commande sur chaque argument individuellement , un à la fois. Je ne pense pas que cela soit complètement évident dans la documentation de Linux xargs -I option mais c'est ce qu'ils veulent dire.

-I replace-str
       Replace occurrences of replace-str in the initial-arguments with
       names read from standard input.  Also, unquoted  blanks  do  not
       terminate  input  items;  instead  the  separator is the newline
       character.  Implies -x and -L 1.
Nicole Hamilton
la source
1
Also, unquoted blanks do not terminate input items; instead the separator is the newline character. - cela est essentiel pour comprendre le comportement. Sans pour autant -I, xargs ne voit l'entrée que sous la forme d'un seul champ, car newline n'est pas un séparateur de champ. Avec -I, soudainement newline est un séparateur de champ, et donc xargs voit trois champs (qu'il itère sur). C’est un vrai point subtil, mais est expliqué dans le man citations de page.
Daniel Andersson
@ DanielAndersson C'est vrai, mais ce n'est pas ce que le PO a trouvé déroutant.
Nicole Hamilton
0

Si vous utilisez GNU Parallel au lieu de xargs, vous pouvez contrôler le comportement souhaité:

# 1 line at a time
echo "$var" | parallel echo ABC {}
# Many lines at a time (divided by # cpu)
echo "$var" | parallel -X echo ABC {} 
# Many lines at a time (not divided)
echo "$var" | parallel -Xj1 echo ABC {} 

Il faut littéralement 10 secondes pour installer GNU Parallel:

wget pi.dk/3 -qO - | sh -x

Regardez les vidéos d'introduction pour en savoir plus: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Ole Tange
la source
- Littéralement. Quoi qu'il en soit, cette question concerne xargs. Pas parallèle. Le parallèle n'est pas posix
Wyatt8740