xargs --replace / -I para argumentos únicos

10

Estou tentando usar o xargs para executar um comando para cada argumento fornecido, mas infelizmente o sinalizador --replace / -I não parece funcionar corretamente quando conjugado com -n. Parece que {} se expandirá para a lista completa de argumentos lidos pelo stdin, independentemente da opção -n.

Infelizmente, todos os exemplos na Web parecem ser para comandos (mv, cp, rm) que receberão vários argumentos onde {} é expandido.

Por exemplo, ao executar:

echo a b c d | xargs -n 1 -I {} echo derp {}

A saída é:

derp a b c d

Mas eu esperava:

derp a
derp b
derp c
derp d

No entanto, executá-lo sem -I {} gera o resultado esperado:

echo a b c d | xargs -n 1 echo derp
derp a
derp b
derp c
derp d

Existe alguma maneira de conseguir isso com xargs? Minha intenção final é usá-lo para executar várias sessões (parralel) ssh, como

echo server{1..90} | xargs -n 1 -P 0 -I {} ssh {} 'echo $SOME_HOST_INFO'

Estou executando xargs (GNU findutils) 4.4.2no RHEL 6.3.

André Fernandes
fonte
2
Curiosamente, ele funciona como você pretende com o BSD xargs, mas não o GNU xargs.
slhck
1
man xargson -I: Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.Por isso, comporta-se como projetado.
Daniel Beck
@ André, já que sua intenção é executar taks em paralelo, você deu uma olhada no GNU paralelo? Faz o trabalho bem. Isenção de responsabilidade: Eu o empacotei para o Debian.
Rbrito
O paralelo GNU parecia um bom substituto, mas infelizmente não consigo instalá-lo neste host em particular.
André Fernandes
@ AndréFernandes Você pode elaborar se a razão não é coberto por oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange

Respostas:

5

Você pode ecoar com novas linhas para alcançar o resultado esperado. No seu caso com a expansão do servidor, seria:

$ echo -e server{1..4}"\n" | xargs -I{} echo derp {}
derp server1
derp server2
derp server3
derp server4
ahilsend
fonte
A idéia da nova linha contorna o problema (mas não com o exemplo exato): echo server {1..4} | tr '' '\ n' | xargs -I {} echo derp {} derp derp server1 server2 derp derp server3 Server4
André Fernandes
Desculpe, testei com zsh... Corrigida minha resposta. echoprecisa da -eopção.
ahilsend
2

Você pode usar um tubo extra como este,

echo a b c d | xargs -n1 | xargs -I{} echo derp {}
derp a
derp b
derp c
derp d

O uso intermediário de xargs 'echos' cada letra 'abcd' individualmente devido à opção '-n1'. Isso coloca cada letra em sua própria linha como esta,

echo a b c d | xargs -n1
a
b
c
d 

É importante entender ao usar -I (substituição de string), xargs implica -L, que executa o comando do utilitário (no seu caso echo) uma vez por linha. Além disso, você não pode usar -n com -L, pois eles são mutuamente exclusivos.

synergy77
fonte