Day 41 - Xargs

22 May 2017

For complex scripts, sometimes you need to pass to a command the previous command output, as an argument.

xargs, followed by a command, will use every xargs inputs as argument.

$ echo /etc/passwd | xargs wc -l

# is equal to:

$ wc -l /etc/password

The wrong way:

# Print every *.js of a directory (and sub-directories)
$ cat $(find . -name *.js)

The clean way:

# Print every *.js of a directory (and sub-directories)
$ find . -name *.js | xargs cat

:warning: Xargs put inputs in a buffer before running the command.

Running a command for each input

Using the argument -I followed by a pattern make your command executed for each input.

$ find . -name *.js | xargs -I {} wc -l {}

# is equal to

$ wc -l foobar.js
$ wc -l barfoo.js
$ wc -l foofoo.js
$ wc -l barbar.js
...

:bulb: “{}” can replaced by any character/pattern and must be identical everywhere in your command.

Example:

# Fetch every repos on your disk, before going offline.
ls ~/projects | xargs -I {} sh -c 'cd {} && git fetch'