xargs --replace / -I per singoli argomenti


10

Sto cercando di usare xargs per eseguire un comando per ogni argomento fornito, ma sfortunatamente il flag --replace / -I non sembra funzionare correttamente quando coniugato con -n. Sembra che {} si espanderà nell'elenco completo degli argomenti letti da stdin, indipendentemente dall'opzione -n.

Sfortunatamente tutti gli esempi sul web sembrano essere per comandi (mv, cp, rm) che prenderanno più argomenti in cui {} viene espanso.

Ad esempio, quando si esegue:

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

L'output è:

derp a b c d

Ma mi aspettavo:

derp a
derp b
derp c
derp d

Tuttavia, eseguendolo senza -I {} si ottiene il risultato previsto:

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

C'è un modo per raggiungere questo obiettivo con xargs? La mia ultima intenzione è quella di usarlo per eseguire più sessioni ssh (parralel), come

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

Sto correndo xargs (GNU findutils) 4.4.2su RHEL 6.3.


2
È interessante notare che funziona come previsto con BSD xargs, ma non 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.Quindi si comporta come previsto.
Daniel Beck

@ André, dal momento che la tua intenzione è di eseguire taks in parallelo, hai dato un'occhiata a GNU parallel? Fa bene il lavoro. Disclaimer: lo pacchetto per Debian.
rbrito,

Il parallelo GNU sembrava un buon sostituto, ma sfortunatamente non posso installarlo su questo particolare host.
André Fernandes,

@ AndréFernandes Puoi chiarire se la tua ragione non è coperta da oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange,

Risposte:


5

Puoi fare eco con le nuove righe per ottenere il risultato atteso. Nel tuo caso con l'espansione del server sarebbe:

$ echo -e server{1..4}"\n" | xargs -I{} echo derp {}
derp server1
derp server2
derp server3
derp server4

L'idea newline risolve il problema (ma non con l'esempio esatto): echo server {1..4} | tr '' '\ n' | xargs -I {} echo derp {} derp server1 derp server2 derp server3 derp server4
André Fernandes

Scusa, ho provato con zsh... Risolto il problema . echoha bisogno -edell'opzione.
Ahilsend,

2

Puoi usare una pipa extra come questa,

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

L'uso intermedio di xargs 'echos' ogni lettera 'abcd' singolarmente a causa dell'opzione '-n1'. Questo mette ogni lettera sulla propria riga in questo modo,

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

È importante capire quando si utilizza -I (sostituzione stringa), xargs implica -L, che esegue il comando utility (nel tuo caso echo) una volta per riga. Inoltre, non è possibile utilizzare -n con -L in quanto si escludono a vicenda.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.