Q1Which correctly describes what xargs does?
xargs — Build Commands from Standard Input
Lay standard input out as arguments with echo a b | xargs echo, run one word at a time with -n1, drop values into {} with -I{}, and batch-process find . -name '*.log' | xargs — with diagrams and a live terminal.
Turn Standard Input into Arguments — xargs and -n1
A pipe passes the previous command's output as the next command's standard input. But rm and echo don't read standard input — they only act on the values written as arguments. xargs is the command that takes what it receives on standard input and rearranges it into arguments for the command you write after it, so with echo a b | xargs echo, the a and b become arguments to the trailing echo.
By default, xargs passes the words it receives to a single run, batched together as much as possible. Add -n1 and it splits them up, running the command once per word.
| Syntax | What it does |
|---|---|
| xargs | Lay out the input as arguments and run the command |
xargs -n1 | Run the command once per argument |
xargs -I{} | Replace {} with the input and drop it in anywhere |
find ... | xargs | Run a single batch of processing on what was found |
| xargs echo rm | Print the command that would run, to check it first |
echo's output is piped to xargs as standard input and rearranged into arguments. One batched run, or three runs one word at a time — that's the difference -n1 makes.printf 'one two three\n' | xargs echo got: # got: one two three (batched, 1 run)
printf 'one\ntwo\nthree\n' | xargs -n1 echo item: # item: one / item: two / item: three
The Replace String and find Integration — -I{}
xargs -I{} builds the command by dropping each line of input into the position of `{}`. Since {} can go anywhere you like, including the middle of the command, you can run a form like echo file_{}.txt — with fixed text around the value — one line at a time.
When you want to run something on the files find turns up, the find ... | xargs form is the standard. xargs lays out the paths that find prints as arguments and runs a single batch of processing over the search results. Combine it with -I{} and you can process each path found by dropping them one at a time into `{}`.
find prints are passed to xargs as one line = one item, and -I{} drops each into `{}` and runs them one at a time.printf 'alpha\nbeta\n' | xargs -I{} echo 'name = {}' # name = alpha / name = beta
mkdir -p logs # create the source directory
touch logs/a.log logs/b.log # create 2 files
find logs -name '*.log' | xargs -I{} echo 'found {}' # found logs/a.log / found logs/b.log
Processing One at a Time — Choosing Between -n1 and -I{}
Both -n1 and -I{} run the command one item at a time, but they differ in where the value goes and how the input is split. -n1 passes words (chunks separated by spaces or newlines) one by one as trailing arguments to the command. -I{} takes lines one by one and drops them into the position where you wrote `{}`.
Use `-n1` when you just need the value at the end, and `-I{}` when you want fixed text around the value, like {}.bak.
| Aspect | `-n1` | `-I{}` |
|---|---|---|
| Where the value goes | Lines up at the end of the command | Goes where you wrote {} |
| Unit of splitting | Words (split on spaces/newlines) | Lines (one line = one item) |
| Best for | Just passing arguments in turn | Building a form with fixed text around the value |
printf 'a\nb\n' | xargs -n1 echo prefix # prefix a / prefix b (at the end)
printf 'a\nb\n' | xargs -I{} echo {}_done # a_done / b_done (dropped in mid-command)
Batch Processing in Practice — Check Before You Run
In real work, you use xargs for batch copies and batch deletes over the targets find collects. Since -I{} can drop the same value into two or more spots, it works with commands that take two arguments like cp source dest, letting you create "original name + .bak" backups all at once.
Don't run irreversible operations like rm straight away. If you run xargs echo rm before xargs rm, the command that would run is merely printed and nothing gets deleted. Check the listed targets, then drop the echo and run it for real — this check-then-run, two-step approach is the safe way to go.
echo in before rm to check the targets by printing them first, then run.mkdir -p cache
touch cache/a.tmp cache/b.tmp
find cache -name '*.tmp' | xargs echo rm # just prints rm cache/a.tmp cache/b.tmp
find cache -name '*.tmp' | xargs rm # run for real once verified
Knowledge Check
Answer each question one by one.
Q2How does printf 'a\nb\nc\n' | xargs -n1 echo behave?
Q3What does {} represent in xargs -I{}?