it-swarm.com.de

Übergabe mehrerer Parameter über xargs

Ich möchte in der Lage sein, xargs zu verwenden, um mehrere Parameter in verschiedenen Teilen eines Befehls auszuführen.

Zum Beispiel Folgendes:

echo {1..8} | xargs -n2 | xargs -I v1 -I v2 echo the number v1 comes before v2

Ich würde hoffen, dass es zurückkehren würde

the number 1 comes before 2
the number 3 comes before 4 

... usw

Ist das erreichbar? Ich vermute, dass meine mehrfache Verwendung von -I ist falsch.

15
Damien Sawyer

Ich glaube, dass Sie -I Auf diese Weise nicht verwenden können. Sie können jedoch den gewünschten Effekt/das gewünschte Verhalten erzielen, indem Sie sagen:

echo {1..8} | xargs -n2 sh -c 'echo "the number $1 comes before $2"' sh

Dadurch wird im Wesentlichen ein einzeiliges Shell-Skript ad hoc erstellt, das xargs über sh -c Ausführt. Die beiden Werte, die xargs aus der Eingabe heraus analysiert, werden an dieses „Skript“ übergeben. Die Shell weist diese Werte dann $1 Und $2 Zu, auf die Sie dann im „Skript“ verweisen können.

26
Scott

Im speziellen Fall von printf können Sie immer Folgendes tun:

echo {1..8} | xargs printf 'the number %s comes before %s\n'

weil printf eine intrinsische xargs-ähnliche Fähigkeit hat, mehrmals ausgeführt zu werden, wenn mehr Argumente angegeben werden, als für einen einzelnen Aufruf erforderlich sind. Das hat aber wenig Vorteil gegenüber

printf 'the number %s comes before %s\n' {1..8}

Bei großen Listen kann der einfache Befehl xargs dazu führen, dass xargs mehrere Instanzen von printf ausführt, von denen einige möglicherweise eine ungerade Anzahl von Argumenten enthalten. Sie könnten -n 1000 bis xargs, um sich dagegen zu schützen, wobei 1000 eine gerade Zahl ist, die klein genug sein sollte, um die Grenze von Argumentliste zu lang nicht zu erreichen, und groß genug, um dies zu vermeiden viele printfs.

Beachten Sie, dass xargs nicht das integrierte printf Ihrer Shell aufrufen würde, sondern das externe printf, bei jedem Aufruf in einem separaten neuen Prozess.

Beachten Sie auch, dass für eine leere Eingabe, außer bei einigen BSDs, printf einmal ohne Argument ausgeführt wird. GNU xargs und kompatibel haben ein -r (oder --no-run-if-empty) Option, um dies zu vermeiden.

Um es klar auszudrücken, diese einfache Antwort ist spezifisch für Ihr Beispiel printf und würde in dem allgemeinen Fall nicht funktionieren, in dem Sie zwei Parameter gleichzeitig an Ihren Befehl übergeben müssen (wie dies bei diff, beispielsweise). Um das allgemeine Problem mit zsh zu lösen, können Sie Folgendes verwenden:

for i j ({1..8}) echo the number $i comes before $j
4

versuche dies:

echo {1..8} |xargs -n 2 bash -c 'echo "the number $0 comes before $1"'
2
md11235