Xargs `-J` Option

optionsxargs

This site presents the xargs command with a -J option making able to pass the standard input into a desired position at the command argument:

find . -name '*.ext' -print0 | xargs -J % -0 rsync -aP % user@host:dir/

but at a GNU xargs man page this option is not present.

Which is the way to do this on, for commands accepting this?

Best Answer

I am not sure this is what you were expecting, but in the BSD world (such as macOS) -I and -J differ in how they pass the multiple "lines" to the command. Example:

$ 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

So with -I, xargs will run the command for each element passed to it individually. With -J, xargs will execute the command once and concatenate all the elements and pass them as arguments all together.

Some commands such as rm or mkdir can take multiple arguments and act on them the same way as if you passed a single argument and ran them multiple times. But some apps may change depending how you pass arguments to them. For instance the tar. You may create a tar file and then add files to it or you may create a tar file by adding all the files to it in one go.

$ find . -iname "*.txt" -or -iname "*.pdf" -print0 | xargs -0 -J % tar cjvf documents.tar.bz2 %
Related Question