Según la documentación de POSIX, xargs debería ejecutar la utilidad dada con argumentos delimitados por espacios o saltos de línea, y esto es lo que sucede en los dos primeros ejemplos suyos.
Sin embargo, cuando --replace (o -I ), solo las líneas nuevas delimitarán los argumentos. El remedio es dar xargs argumentos en líneas separadas:
$ printf '%s\n' a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c y
Usando opciones POSIX:
printf '%s\n' a b c | xargs -n 1 -I "{}" echo x "{}" y
Aquí, doy xargs no una línea sino tres. Toma una línea (como máximo) y ejecuta la utilidad con eso como argumento.
Tenga en cuenta también que -n 1 (o --max-args=1 ) en lo anterior no es necesario ya que es el número de reemplazos realizados por -I que determina el número de argumentos utilizados:
$ printf '%s\n' a b c | xargs -I "{}" echo x "{}" y
x a y
x b y
x c y
De hecho, la sección Justificación de la especificación POSIX en xargs dice (énfasis mío)
El -I , -L y -n las opciones son mutuamente excluyentes . Algunas implementaciones usan el último especificado si se proporciona más de uno en una línea de comando; otras implementaciones tratan las combinaciones de las opciones de diferentes maneras.
Mientras probaba esto, noté que la versión de OpenBSD de xargs hará lo siguiente si -n y -I se usan juntos:
$ echo a b c | xargs -n 1 -I "{}" echo x "{}" y
x a y
x b y
x c y
Esto es diferente de lo que xargs de GNU coreutils hace (que produce x a b c y ). Esto se debe a que la implementación acepta espacios como delimitador de argumento con -n , aunque -I se usa Entonces, no uses -I y -n juntos (no es necesario de todos modos).