xargs --replace / -I für einzelne Argumente

10

Ich versuche, mit xargs einen Befehl für jedes angegebene Argument auszuführen, aber leider scheint das Flag --replace / -I nicht richtig zu funktionieren, wenn es mit -n konjugiert wird. Es scheint, dass {} unabhängig von der Option -n in die vollständige Liste der von stdin gelesenen Argumente erweitert wird.

Leider scheinen alle Beispiele im Web Befehle zu sein (mv, cp, rm), die mehrere Argumente annehmen, wobei {} erweitert wird.

Zum Beispiel beim Ausführen:

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

Die Ausgabe ist:

derp a b c d

Aber ich habe erwartet:

derp a
derp b
derp c
derp d

Wenn Sie es jedoch ohne -I {} ausführen, erhalten Sie das erwartete Ergebnis:

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

Gibt es eine Möglichkeit, dies mit xargs zu erreichen? Meine ultimative Absicht ist es, damit mehrere (parralel) ssh-Sitzungen auszuführen, wie z

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

Ich laufe xargs (GNU findutils) 4.4.2auf RHEL 6.3.

André Fernandes
quelle
2
Interessanterweise funktioniert es so, wie Sie es mit BSD beabsichtigen xargs, aber nicht mit 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.Es verhält sich also wie geplant.
Daniel Beck
@ André, da Sie beabsichtigen, Takes parallel auszuführen, haben Sie sich GNU parallel angesehen? Es macht den Job gut. Haftungsausschluss: Ich verpacke es für Debian.
Rbrito
GNU parallel schien ein guter Ersatz zu sein, aber leider kann ich es nicht auf diesem bestimmten Host installieren.
André Fernandes
@ AndréFernandes Können Sie näher erläutern, wenn Ihre Vernunft nicht von oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange

Antworten:

5

Sie können mit Zeilenumbrüchen wiederholen, um das erwartete Ergebnis zu erzielen. In Ihrem Fall mit der Servererweiterung wäre das:

$ echo -e server{1..4}"\n" | xargs -I{} echo derp {}
derp server1
derp server2
derp server3
derp server4
ahilsend
quelle
Die Newline-Idee umgeht das Problem (nur nicht mit Ihrem genauen Beispiel): Echoserver {1..4} | tr '' '\ n' | xargs -I {} echo derp {} derp server1 derp server2 derp server3 derp server4
André Fernandes
Sorry, habe es getestet mit zsh... Meine Antwort wurde korrigiert. echobraucht die -eOption.
Ahilsend
2

Sie können ein zusätzliches Rohr wie dieses verwenden,

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

Die Zwischenverwendung von xargs 'echos' für jeden Buchstaben 'abcd' aufgrund der Option '-n1' einzeln. Dies setzt jeden Buchstaben in eine eigene Zeile wie folgt:

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

Es ist wichtig zu verstehen, dass bei Verwendung von -I (String-Ersetzung) xargs -L impliziert, das den Dienstprogrammbefehl (in Ihrem Fall echo) einmal pro Zeile ausführt. Sie können -n auch nicht mit -L verwenden, da sie sich gegenseitig ausschließen.

Synergie77
quelle