Selon la documentation POSIX, xargs devrait exécuter l'utilitaire donné avec des arguments délimités par des espaces ou des retours à la ligne, et c'est ce qui se passe dans les deux premiers exemples que vous avez.
Cependant, lorsque --replace (ou -I ) est utilisé, seules les nouvelles lignes délimiteront les arguments. Le remède est de donner xargs arguments sur des lignes séparées :
$ printf '%s\n' a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c y
Utilisation des options POSIX :
printf '%s\n' a b c | xargs -n 1 -I "{}" echo x "{}" y
Ici, je donne xargs pas une ligne mais trois. Il prend une ligne (au plus) et exécute l'utilitaire avec cela comme argument.
Notez également que -n 1 (ou --max-args=1 ) ci-dessus n'est pas nécessaire car il s'agit du nombre de remplacements effectués par -I qui détermine le nombre d'arguments utilisés :
$ printf '%s\n' a b c | xargs -I "{}" echo x "{}" y
x a y
x b y
x c y
En fait, la section Rationale de la spécification POSIX sur xargs dit (c'est moi qui souligne)
Le
-I,-L, et-nles options sont mutuellement exclusives . Certaines implémentations utilisent la dernière spécifiée si plus d'une est donnée sur une ligne de commande ; d'autres implémentations traitent les combinaisons d'options de différentes manières.
En testant cela, j'ai remarqué que la version OpenBSD de xargs fera ce qui suit si -n et -I sont utilisés ensemble :
$ echo a b c | xargs -n 1 -I "{}" echo x "{}" y
x a y
x b y
x c y
Ceci est différent de ce que xargs de GNU coreutils fait (ce qui produit x a b c y ). Cela est dû au fait que l'implémentation accepte les espaces comme délimiteur d'argument avec -n , même si -I est utilisé. Donc, n'utilisez pas -I et -n ensemble (ce n'est pas nécessaire de toute façon).