Problema ao usar xargs --max-args --replace com o delimitador padrão

5

Isso funciona como esperado:

$ echo a b c | xargs --replace="{}" echo x "{}" y
x a b c y

Isso também acontece:

$ echo a b c | xargs --max-args=1 echo x
x a
x b
x c

Mas isso não funciona como esperado:

$ echo a b c | xargs --max-args=1 --replace="{}" echo x "{}" y
x a b c y

E nem isso:

$ echo a b c | xargs --delimiter=' ' --max-args=1 --replace="{}" echo x "{}" y
x a y
x b y
x c
 y

Eu esperava essa saída:

x a y
x b y
x c y

Como solução alternativa, estou usando printf e dois xargs, mas isso é feio:

$ echo a b c | xargs printf '%s
$ echo a b c | xargs --replace="{}" echo x "{}" y
x a b c y
' | \ > xargs --null --max-args=1 --replace="{}" echo x "{}" y x a y x b y x c y

Alguma idéia do porquê isso está acontecendo?

    
por Pedro Gimeno 05.03.2018 / 17:04

1 resposta

4

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 -n options 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).

    
por 05.03.2018 / 17:09

Tags