Linux: xargs

By Xah Lee. Date: .

xargs

xargs is a command that is used together with find to allow you to call arbitrary unix commands on list of files.

there are many version of xargs, their options are incompatible.

on this page, we talk about gnu xargs.

use “find” on file names that may contain spaces or dash

# print file names that may contain spaces
find . -print0 | xargs -0 -l -i echo "{}";
-print0
use null char (ASCII 0) as file name separator. (by default -print uses newline character.)

Here's the options used for xargs:

-0
parse input using null char as seperators and take any special char in file name as literal.
-l
pass just one file name at a time.
-i
use {} as placeholder for file name.
"{}"
Quote around the entire file name, so that echo (or another program) will see it as one argument instead of several. (Note: the -i must come after -l)

Here's a useful example:

# convert all png in a dir to jpg
# file name should not contain ttt. if so, change ttt to hhh or something random

find . -name "*png" -print0 | xargs -0 -L1 -I ttt magick ttt ttt.jpg

Use GNU Parallel for xargs

Note: a modern replacement for xargs is GNU parallel. The syntax is almost indentical to xargs, except it runs in parallel. It also doesn't have problems with file names containing quotes or apostrophes.

Thanks to author of GNU Parallel, Ole Tange for telling me about it.

gnu xargs

write a tutorial on gnu xargs

ai answer

GNU xargs is a command-line utility that reads items from standard input (or a file) and builds + executes command lines with those items as arguments. It is part of GNU findutils and is the version found on most Linux systems.

Its main purpose is to solve two problems:

Basic Syntax

command | xargs [options] [command [initial-arguments]]

If no command is given, xargs defaults to /bin/echo.

Simple Examples

# List files and pass them to ls -l
ls | xargs ls -l

# Delete every .tmp file found by find
find . -name '*.tmp' | xargs rm

# Count lines in every C source file
find . -name '*.c' | xargs wc -l

Controlling How Arguments Are Grouped

Option Meaning Example
-n N Use at most N arguments per command invocation ... | xargs -n 1 echo
-L N Use at most N non-empty input lines ... | xargs -L 2
-I {} Replace {} (or any placeholder) with the entire input line ... | xargs -I {} mv {} {}.bak
-i Same as -I {} (deprecated)
# One file per rm invocation (safe with spaces if combined with -0)
find . -name '*.o' -print0 | xargs -0 -n 1 rm

# Rename every file by appending .bak
ls *.txt | xargs -I {} mv {} {}.bak

Handling Whitespace and Special Characters (Critical)

By default xargs splits on any whitespace and treats quotes/\ specially. This breaks on filenames that contain spaces, newlines, or quotes.

Always prefer null-terminated input when dealing with arbitrary filenames:

# The safe, recommended pattern
find . -name '*.log' -print0 | xargs -0 rm

# Or with GNU find’s -exec + (also null-safe and often faster)
find . -name '*.log' -exec rm {} +

Other useful options:

# Process a newline-separated list safely
xargs -d '\n' -a filelist.txt rm

Parallel Execution

GNU xargs can run multiple processes at once:

# Run up to 4 compressions in parallel
find . -name '*.txt' -print0 | xargs -0 -P 4 gzip

# Unlimited parallelism (use with care)
... | xargs -P 0 ...

-P N is a GNU extension and is extremely useful for CPU-bound or I/O-bound batch jobs.

Interactive and Debugging Options

Option Purpose
-t / --verbose Print the command line before executing it
-p / --interactive Ask for confirmation before each command
-r / --no-run-if-empty Do not run the command if stdin is empty (GNU)
-s max-chars Limit the total length of the command line
find . -name '*~' -print0 | xargs -0 -t -p rm

Other Useful GNU Options

Practical Recipes

1. Safely delete files found by find

find /tmp -name 'core.*' -print0 | xargs -0 -r rm -f

2. Copy a list of files while preserving relative paths

find src -name '*.h' -print0 | xargs -0 -I {} cp --parents {} /backup/

3. Parallel image conversion

find . -name '*.png' -print0 | xargs -0 -P $(nproc) -I {} convert {} {}.jpg

4. Feed a command that only accepts one argument at a time

cat urls.txt | xargs -n 1 -P 8 curl -O

5. Combine with printf for complex argument construction

printf '%s\0' *.c | xargs -0 gcc -c

Common Pitfalls

  1. Forgetting -0 / -print0 → filenames with spaces or newlines break.
  2. Using -I with multiple arguments-I forces one input item per command; combine carefully with -n.
  3. Empty input → without -r, xargs still runs the command once with no arguments.
  4. Assuming order is preserved under -P → parallel runs are unordered.
  5. Very long argument lists → even with batching, some systems have hard limits; use -n or -s.

xargs vs. Alternatives

Situation Prefer
Simple batching of arguments xargs
Safe handling of arbitrary names find … -exec … + or xargs -0
Complex per-item logic while read loop or GNU Parallel
Maximum performance / features GNU Parallel

Quick Reference Card

# Safe delete
find … -print0 | xargs -0 -r rm

# One item at a time, parallel
… | xargs -0 -n 1 -P 4 command

# Replace placeholder
… | xargs -I {} command {} extra-args

# Custom delimiter + verbose
xargs -d ',' -t -a list.csv command

GNU xargs is small, fast, and available everywhere. Mastering the combination of -0, -n/-I, -P, and -r covers the vast majority of real-world use cases.

Linux, Files and Dirs