Xargs -I option

xargs

The xargs manual says :

-I replace-str
–replace[=replace-str]
-i[replace-str]
Replace occurrences of replace-str in the initial arguments with names read from standard input.

I don't understand this part: with names read from standard input.

For example what is happening with:

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0I{} echo | wc -l

The above piece of code counts the total files/directories inside a directory.

Could anybody explain this for me?

Best Answer

"with names read from standard input" means that xargs takes the data coming in on its standard input, splits it up, and uses it to run the command given in its arguments. By default, it splits on blanks or newlines, and runs echo with as many arguments at a time as possible.

The -0 option in your example instructs xargs to split its input on null bytes instead of blanks or newlines. Combined with find's -print0, this allows filenames containing blanks or newlines to be handled properly.

The -I option changes the way the new command lines are built. Instead of adding as many arguments as possible at a time, xargs will take one name at a time from its input, look for the given token ({} here) and replace that with the name.

In your example, {} isn't present in the command template given to xargs, so in effect xargs is instructed to run echo with no argument, once for every filename given to it by find. To see this, drop the wc:

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0I{} echo

You'll see a series of blank lines... Compare this with

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0I{} echo {}

and

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 echo

and

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0

to get a better understanding.

Related Question