Diese Seitestellt dem xargs
Befehl eine -J
Option zur Verfügung, die es ermöglicht, die Standardeingabe an einer gewünschten Stelle als Befehlsargument zu übergeben:
find . -name '*.ext' -print0 | xargs -J % -0 rsync -aP % user@host:dir/
aber bei einemGNU xargs-Manpagediese Option ist nicht vorhanden.
Wie kann dies bei Befehlen durchgeführt werden, die dies akzeptieren?
Antwort1
Ich bin nicht sicher, ob das das ist, was Sie erwartet haben, aber in der BSD-Welt (wie etwa macOS) gibt -I
es -J
Unterschiede in der Art und Weise, wie die mehreren „Zeilen“ an den Befehl übergeben werden. Beispiel:
$ ls
file1 file2 file3
$ find . -type f -print0 | xargs -I % rm %
rm file1
rm file2
rm file3
$ find . -type f -print0 | xargs -J % rm %
rm file1 file2 file3
Mit -I
führt xargs den Befehl für jedes übergebene Element einzeln aus. Mit -J
führt xargs den Befehl einmal aus, verkettet alle Elemente und übergibt sie alle zusammen als Argumente.
Einige Befehle wie rm
oder mkdir
können mehrere Argumente annehmen und auf diese genauso reagieren, als ob Sie ein einzelnes Argument übergeben und sie mehrmals ausführen würden. Einige Apps können sich jedoch ändern, je nachdem, wie Sie ihnen Argumente übergeben. Beispielsweise das tar
. Sie können eine Tar-Datei erstellen und dann Dateien hinzufügen, oder Sie können eine Tar-Datei erstellen, indem Sie ihr alle Dateien auf einmal hinzufügen.
$ find . -iname "*.txt" -or -iname "*.pdf" -print0 | xargs -0 -J % tar cjvf documents.tar.bz2 %
Antwort2
Wenn dies das -J
Flag für die BSD-Version von ist, xargs
glaube ich nicht, dass es eine exakt äquivalente Option für GNU gibt xargs
. -J
ersetzt ein einzelnes Vorkommen vonreplstr(zB %
) wobei jede Zeile über die Standardeingabe kommt. Die GNU-Version hat eineähnlichOption, aber: -I
1 . Sie können jedoch verwendenreplstrmehrmals mit dieser Flagge.
Für Anwendungsfälle, in denen es unwichtig ist, ob ein oder mehrere Befehlsaufrufe erfolgen, sollten Sie GNU xargs -I
als Drop-In-Ersatz verwenden können. Aber Ihr Beispiel verwendet rsync
und ich bin sicher, dass Sie keine Mehrfachaufrufe davon möchten.
Dann ist es am besten, Alternativen zu erwägen, die mit find
und der Aktion -exec
„oder“ beginnen -execdir
. Davon gibt es zwei Varianten. Eine ist analog zu GNU -I
und die andere zu BSD -J
. Sehen Sie sich diese Beispiele an …
# Note the escaping of ';'
$ find /tmp -name '*.txt' -exec echo {} \;
/tmp/a.txt
/tmp/b.txt
..
/tmp/z.txt
Vergleichen Sie das nun mit diesem:
$ find /tmp -name '*.txt' -exec echo {} +
/tmp/a.txt /tmp/b.txt .. /tmp/z.txt
Der einzige Unterschied zwischen den beiden besteht darin, welcher „Modifikator“ am Ende erscheint, +
oder ;
.
1 Weitere verwirrende Dinge sind, dass die BSD-Version auch hat und in der Funktion sowohl als auch GNU -I
ähnlich ist ! Dies wird jedoch von anderen Flags beeinflusst und ist höchstwahrscheinlich nicht das, wonach Sie suchen.-J
-I
-I