De acordo com a documentação do POSIX , xargs deve executar o utilitário fornecido com argumentos delimitado por espaços ou novas linhas, e é isso que acontece nos dois primeiros exemplos de vocês.
No entanto, quando --replace (ou -I ) é usado, somente novas linhas delimitarão os argumentos. A solução é fornecer xargs argumentos em linhas 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 opções POSIX:
printf '%s\n' a b c | xargs -n 1 -I "{}" echo x "{}" y
Aqui, dou xargs não uma linha, mas três. Leva uma linha (no máximo) e executa o utilitário com isso como argumento.
Observe também que -n 1 (ou --max-args=1 ) no acima não é necessário, pois é o número de substituições feitas por -I que determina o número de argumentos usados:
$ printf '%s\n' a b c | xargs -I "{}" echo x "{}" y
x a y
x b y
x c y
Na verdade, a seção Rationale da especificação POSIX em xargs diz (minha ênfase)
The
-I,-L, and-noptions are mutually-exclusive. Some implementations use the last one specified if more than one is given on a command line; other implementations treat combinations of the options in different ways.
Enquanto testava isso, notei que a versão do xargs do OpenBSD faria o seguinte se -n e -I fossem usados juntos:
$ echo a b c | xargs -n 1 -I "{}" echo x "{}" y
x a y
x b y
x c y
Isso é diferente do que o GNU coreutils ' xargs faz (que produz x a b c y ). Isso ocorre devido à implementação de aceitar espaços como delimitador de argumentos com -n , mesmo que -I seja usado. Portanto, não use -I e -n juntos (não é necessário de qualquer maneira).