xargs builds command lines out of piped input. Pipes normally connect stdout to stdin, but many commands want their data as arguments — and that gap between streams and arguments is exactly what xargs bridges.
The basic bridge #
$ cat urls.txt | xargs curl -s -O
$ ls *.png | xargs -n 1 file
The second example shows -n 1: run the command once per line, one argument at a time. Without it, xargs packs as many arguments per invocation as the command line allows — usually what you want for bulk jobs.
The flags that matter #
| Flag | Effect |
|---|---|
-n N | At most N arguments per run |
-I {} | Insert each item at {} in a template |
-P 4 | Run 4 commands in parallel |
-0 | NUL-separated input, for find -print0 |
--no-run-if-empty | Skip the run when input is empty |
-I {} earns its keep when the argument sits mid-command:
$ cat keep.txt | xargs -I {} mv {} archive/
find and xargs, properly paired #
The canonical combination — find locates, xargs acts — has one famous trap: filenames with spaces break the naive form. The fix is the NUL-delimited pair:
$ find . -name "*.log" -print0 | xargs -0 -n 1 gzip
-print0 and -0 speak a private delimiter that no filename can contain. See find for the locating half.
Parallelism is the quiet superpower — a four-core machine compressing in parallel:
$ find . -name "*.tar" -print0 | xargs -0 -P 4 -n 1 gzip -9
For counting and shaping the lines before they become arguments, sort and uniq and grep sit naturally upstream. More assembly-line patterns are in unix pipes in practice, part of the terminal notes.
