xargs Command: Usage, the -n and -I Options and Using It with find

Test environmentRHEL familyAlmaLinux 9.8root accountChecked 2026-10-29

The xargs command is a Linux tool that turns lines and words received on standard input into arguments for another command and runs it. When we passed three log files found by find to wc through xargs in a working folder on an AlmaLinux 9 server, one file with a space in its name was split in two and caused an error, and with -print0 and -0 the line counts of all three files appeared.

The output below was run inside a working folder under the root account on an AlmaLinux 9.8 server. The name list, logs and temporary files are sample files made for testing, and the IP addresses and working folder paths in them are also example values.

1️⃣ Basic xargs command usage

  • ↪️ Standard input as command arguments

xargs splits the standard input passed by the previous command on spaces and newlines, and runs the command written after it with those pieces in its argument positions. We checked this with names.txt, which holds one name per line.

cat names.txt
alice
bob
carol
dave
erin

Passing the output of cat to xargs echo turns the five lines into arguments of a single echo, printed on one line.

cat names.txt | xargs echo
alice bob carol dave erin

If you write no command after it, xargs runs echo, so the result is the same.

cat names.txt | xargs
alice bob carol dave erin

A pipe connects the output of the previous command to the standard input of the next one, so nothing goes into the next command's argument positions. If you only pipe list.txt, which holds three file names, to wc -l, wc counts the 3 lines of the list itself.

cat list.txt
logs/access.log
logs/error.log
tmp/keep.txt
cat list.txt | wc -l
3

With xargs in between, the three names in the list become arguments of wc, and the line count appears for each file.

cat list.txt | xargs wc -l
  3 logs/access.log
  2 logs/error.log
  1 tmp/keep.txt
  6 total

2️⃣ The xargs -n and -I options

  • ↪️ Batch size, argument position and checking with -t

Without options, all input goes into one run of the command, so to repeat the command, use -n to set how many arguments are passed at a time. The figure below shows how the same five names are grouped depending on the option.

🧩 How xargs groups standard input into command arguments
Explainer diagram
⚙️ Option
$ cat names.txt | xargs echo
$ cat names.txt | xargs -n 2 echo
$ cat names.txt | xargs -I {} echo 'user: {}'
① Standard input (names.txt)alicebobcaroldaveerinOne name per line, five lines.
② Grouping into argumentsalicebobcaroldaveerinWithout options, the five form one group.alicebobcaroldaveerin-n 2 groups them in twos and puts the one left over in its own group.alicebobcaroldaveerin-I {} treats one line as one group and puts it in place of {}.
③ Commands run and outputecho alice bob carol dave erinalice bob carol dave erinecho runs once.echo alice bobecho carol daveecho erinecho runs three times, printing one line per group.echo 'user: alice' echo 'user: bob' … five times in the same form up to erinuser: aliceuser: bobuser: caroluser: daveuser: erinecho runs five times, with a name in place of {}.
Without options, xargs attaches every word read from input as arguments to a single run of the command. The five names go to one echo and print on one line.
With -n 2, words are grouped in twos and the command is repeated. The five names form three groups, so echo runs three times.
With -I {}, one line counts as one unit, and that line goes in place of {} in the command, which runs once per line. Use it when an argument must go somewhere other than the very end.

-n 1 runs echo for each name, printing five lines.

cat names.txt | xargs -n 1 echo
alice
bob
carol
dave
erin

-n 2 groups them in twos and passes the one left over on its own.

cat names.txt | xargs -n 2 echo
alice bob
carol dave
erin

To see the commands being run, add -t. The command line appears first, with its output below it.

cat names.txt | xargs -t -n 2 echo
echo alice bob
alice bob
echo carol dave
carol dave
echo erin
erin

If an argument must go somewhere other than the end of the command, set a placeholder with -I. One line goes in place of {} at a time, and if the same text appears several times, all of them are replaced.

cat names.txt | xargs -I {} echo 'user: {}'
user: alice
user: bob
user: carol
user: dave
user: erin
cat names.txt | xargs -I {} echo '{} -> home/{}'
alice -> home/alice
bob -> home/bob
carol -> home/carol
dave -> home/dave
erin -> home/erin

You can make a folder per name in the same way. Create the home folder first, then use -I {} to make a folder per name under it, and five folders appear.

mkdir home
cat names.txt | xargs -I {} mkdir home/{}
ls home
alice  bob  carol  dave  erin

-I treats one line as one argument, so it cannot be used with -n. When we wrote both, -I was ignored with a warning and {} was printed as literal text.

cat names.txt | xargs -I {} -n 2 echo {}
xargs: warning: options --replace and --max-args/-n are mutually exclusive, ignoring previous --replace value
{} alice bob
{} carol dave
{} erin

-L groups by line count. If a line holds several words, the words on that line are passed together, and in names.txt, with one name per line, -L 2 gave the same result as -n 2.

cat names.txt | xargs -L 2 echo
alice bob
carol dave
erin

3️⃣ Combining find and xargs

  • ↪️ Passing file names with spaces using -print0 and -0

You do not have to build a name list by hand; you can pass the files found by find straight to xargs. Looking for files ending in .log in the log folder finds three, and one of them has a space in its name.

find /root/work/logs -name '*.log'
/root/work/logs/access.log
/root/work/logs/error.log
/root/work/logs/old access.log

When this list went straight to xargs wc -l, the name with a space split into old and access.log, giving two error lines, and the total was 5 lines from only two files.

find /root/work/logs -name '*.log' | xargs wc -l
  3 /root/work/logs/access.log
  2 /root/work/logs/error.log
wc: /root/work/logs/old: No such file or directory
wc: access.log: No such file or directory
  5 total

find's -print0 separates names with the null character instead of a newline, and xargs's -0 splits arguments only on that null character. Using both gives the line counts of all three files, including the one with a space.

find /root/work/logs -name '*.log' -print0 | xargs -0 wc -l
  3 /root/work/logs/access.log
  2 /root/work/logs/error.log
  1 /root/work/logs/old access.log
  6 total

find's -exec option does the same job. With + after {}, the found files are passed at once, so the result is the same, and find passes spaces in file names as they are. xargs also accepts output from commands other than find, so use it when input does not come from find alone, or when you need to set how many items are passed at a time (-n) or how many run at once (-P).

find /root/work/logs -name '*.log' -exec wc -l {} +
  3 /root/work/logs/access.log
  2 /root/work/logs/error.log
  1 /root/work/logs/old access.log
  6 total

To pick only the found files containing a string, add grep -l after xargs. Two files contained wp-login: the access log and the error log.

find /root/work/logs -name '*.log' -print0 | xargs -0 grep -l wp-login
/root/work/logs/access.log
/root/work/logs/error.log

4️⃣ Deleting files with the xargs command

  • ↪️ Previewing with echo and confirming with -p

With rm after xargs, the found files are deleted at once, so check which files will be passed before deleting. Putting echo in front of rm prints only the command line that would run, and the files stay in place.

find /root/work/tmp -name '*.tmp' -print0 | xargs -0 echo rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp
ls tmp
cache-a.tmp  cache-b.tmp  cache-c.tmp  keep.txt

With -p, xargs asks whether to run each command. Entering n deletes nothing, so the three temporary files stay.

find /root/work/tmp -name '*.tmp' -print0 | xargs -0 -p rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...n
ls tmp
cache-a.tmp  cache-b.tmp  cache-c.tmp  keep.txt

Entering y deletes the three files, leaving only keep.txt.

find /root/work/tmp -name '*.tmp' -print0 | xargs -0 -p rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...y
ls tmp
keep.txt

If input is empty, xargs runs the command once with no arguments. Passing an empty file runs rm with no arguments and gives the [rm: missing operand] error; with -r, the command does not run at all.

cat empty.txt | xargs rm
rm: missing operand
Try 'rm --help' for more information.
cat empty.txt | xargs -r rm

5️⃣ xargs parallel execution, delimiters and options

  • ↪️ The -P, -d and -a options

🔲 Parallel execution and delimiters

When commands run one at a time, the time grows with the number of targets. -P sets how many commands run at once. Four sleeps waiting 1, 2, 3 and 4 seconds took 10 seconds one after another, and finished in 4 seconds, the longest one, when run together with -P 4.

time seq 1 4 | xargs -n 1 sleep

real	0m10.007s
user	0m0.004s
sys	0m0.003s
time seq 1 4 | xargs -n 1 -P 4 sleep

real	0m4.005s
user	0m0.001s
sys	0m0.006s

If input is split by a symbol rather than newlines or spaces, set the delimiter with -d. Splitting three comma-joined names with -d , prints one line per name.

printf 'alice,bob,carol' | xargs -d , -n 1 echo
alice
bob
carol

To read from a file instead of standard input, give the file name to -a. The five names in names.txt went to echo without a pipe.

xargs -a names.txt echo
alice bob carol dave erin

🔲 xargs command options

📌 Main options: results from this article

OptionTaskResult in this article
-nSets how many arguments are passed to one run of the commandThe five names are grouped in twos by -n 2, and echo runs three times
-IPuts one line at a time into the placeholder and runs per lineA name goes in place of {}; written with -n, -I is ignored with a warning
-LSets how many lines are passed to one run of the commandIn a file with one name per line, same result as -n 2
-tPrints the command line before running itThe command line appears before the output
-0Splits input only on the null character (with find -print0)Without it, names with spaces split, giving two error lines; with it, all three files show 6 lines
-pAsks whether to run each commandn leaves them in place; y deletes the three files
-rDoes not run the command if input is emptyWithout it, [rm: missing operand]; with it, nothing runs
-PSets how many commands run at onceFour sleeps take 10 seconds in turn, 4 seconds with -P 4
-dSets the delimiter that splits input-d , prints one line per name
-aReads input from a file instead of standard inputThe five names in names.txt go to a single echo

📎 Other options: per the official manual

OptionTask
-sSets the maximum characters on one command line
-xBeyond the -s size, ends without running
-EStops reading further input on reaching a line with only this text
-oReopens the terminal as the command's standard input (for interactive programs)
--process-slot-varPuts a different number in an environment variable for each command running at once

🔲 xargs command simulator

In the simulator below, you can type xargs and find commands yourself on the same test files.

xargs command simulatorGNU findutils 4.8
[root@server work]#
Use the ↑↓ keys to recall commands you typed earlier.

🔢 FAQ & Recommended Content

If you pass a process ID, kill sends a signal to that ID. When we took the process ID of sleep 600 run in the background from the shell variable $! and passed it to xargs kill, [Terminated sleep 600] appeared in the job list and the job was gone at the next jobs. When you collect a list of IDs with another command, print it first to see which processes are included before passing it.

The --show-limits option prints the limits. On the server we tested, the POSIX upper limit for command line length was 2,093,890 bytes, and the command buffer xargs actually uses was 131,072 bytes. According to the manual, if input is longer than this buffer, xargs splits the command into several runs.

If any command run by xargs fails with a code from 1 to 125, the exit code of xargs is 123. Both the wc run where a file name with a space was split and the rm run with empty input gave 123, and a command that could not be found gave 127. Use these values when checking the exit code after xargs in shell scripts.

ℹ️ Affiliate Disclosure
This site's content contains affiliate links. When a visitor buys a product or service through one of them, the site receives a commission from the seller. The amount the buyer pays(it goes down during event discounts ↓)does not go up. Posted prices, discounts, and stock reflect the time of writing and may differ, so confirm with the seller before buying. Products are chosen and reviewed by our own standards, and commissions do not affect the order or content of reviews.

Leave a Reply

Your email address will not be published. Required fields are marked *

Prove your humanity: 3   +   8   =