21

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?

1 Answer 1

36

"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.

3
  • Use a subshell if you want to exec 2 commands while using the interpolation param: ..|xargs -0I{} sh -c 'echo {} && echo {}'.
    – Alex
    Jan 7, 2022 at 18:02
  • @Alex that exposes you to incorrect behaviour depending on the characters in your file names; see this answer for a safer approach using xargs and sh. Jan 7, 2022 at 18:59
  • Nice tip. For everyone who doesn't want to navigate away, in order to support single quotes and other strange chars in filenames use: ..| xargs -0I{} sh -c 'echo $1 && ..' sh {}. The last sh is a dummy arg and can (but shouldn't really) be replaced with an arbitrary string.
    – Alex
    Jan 10, 2022 at 11:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .