What it is
xargs builds and executes command lines from standard input, allowing you to process lists of items with arbitrary commands.
Installation
Linux:
sudo apt update && sudo apt install findutils # Debian/Ubuntu
sudo yum install findutils # CentOS/RHEL
sudo dnf install findutils # Fedora
macOS:
xargs is typically pre-installed with macOS. If not:
brew install findutils
(You might need to alias xargs to gxargs if you installed from findutils via Homebrew to avoid conflicts with the built-in xargs).
Windows:
xargs is not a native Windows command. You can achieve similar functionality using PowerShell loops or by installing a Linux environment like WSL (Windows Subsystem for Linux).
Core Concepts
xargs reads items from standard input, delimited by blanks (by default) or newlines, and executes a specified command using these items as arguments. It’s particularly useful for processing the output of other commands like find, grep, or ls.
Commands / Usage
Basic Execution
-
Run a command with arguments from stdin:
echo "file1.txt file2.txt" | xargs touchCreates two empty files named
file1.txtandfile2.txt. -
Run a command with arguments from stdin, one per line:
printf "line1\nline2\nline3\n" | xargs -L 1 echoOutputs:
line1 line2 line3 -
Run a command once with all arguments from stdin:
echo "arg1 arg2 arg3" | xargs echoOutputs:
arg1 arg2 arg3
Controlling Argument Placement
-
Specify where arguments are inserted using
-I(or-i):echo "file1.txt file2.txt" | xargs -I {} mv {} {}.bakRenames
file1.txttofile1.txt.bakandfile2.txttofile2.txt.bak. The{}is a placeholder for the input item. -
Use a different placeholder with
-I:find . -name "*.log" | xargs -I FILENAME cp FILENAME /backup/Copies all
.logfiles found in the current directory and its subdirectories to/backup/, usingFILENAMEas the placeholder.
Controlling Execution Behavior
-
Execute the command only once, regardless of the number of arguments:
ls *.txt | xargs echo "Found:"Outputs:
Found: file1.txt file2.txt ...(all .txt files on one line after "Found:") -
Execute the command multiple times, with a limited number of arguments per execution (
-n):seq 1 10 | xargs -n 3 echoOutputs:
1 2 3 4 5 6 7 8 9 10 -
Execute the command with a maximum number of arguments per line (
-L):printf "a\nb\nc\nd\ne" | xargs -L 2 echoOutputs:
a b c d e(Note:
-Lsplits input by lines,-nsplits input by items and limits how many items go into one command execution). -
Prompt before each command execution (
-p):echo "file1.txt file2.txt" | xargs -p rmWill prompt:
rm file1.txt file2.txt ?(y/n). -
Execute commands in parallel (
-P):find . -name "*.jpg" | xargs -P 4 -I {} convert {} -resize 50% small_{}Resizes all
.jpgfiles in parallel using 4 worker processes, creatingsmall_prefixed versions. -
Specify the maximum number of parallel processes (
-P):seq 1 100 | xargs -P 8 -n 1 sleep 1Runs 100
sleep 1commands, with up to 8 running concurrently.
Handling Special Characters and Whitespace
-
Treat input as null-delimited items (
-0): Essential when dealing with filenames containing spaces, newlines, or other special characters. Often used withfind -print0.find . -name "* *" -print0 | xargs -0 rmSafely removes files with spaces in their names.
-
Change the delimiter (
-d):echo "item1:item2:item3" | xargs -d : echoOutputs:
item1 item2 item3 -
Use specific delimiters for
-I:echo "user1,user2,user3" | xargs -d ',' -I {} echo "Processing user: {}"Outputs:
Processing user: user1 Processing user: user2 Processing user: user3
Other Useful Flags
-
Do not execute, just print the command line (
-t):echo "file1.txt file2.txt" | xargs -t touchPrints:
touch file1.txt file2.txtand then executes it. -
Specify the command to run (
-a): Reads arguments from a file instead of stdin.# Create a file with arguments echo "fileA.txt" > my_files.txt echo "fileB.txt" >> my_files.txt # Use xargs with the file xargs -a my_files.txt touchCreates
fileA.txtandfileB.txt. -
Set the maximum argument list length (
-s): (Rarely needed, defaults are usually fine).# Example: Limit command line length to 100 characters seq 1 1000 | xargs -s 100 echo -
Specify the initial arguments for the command (
--arg-file):# Create a file with initial arguments echo "-l" > options.txt echo "-a" >> options.txt # Use xargs with initial arguments from a file echo "file1.txt file2.txt" | xargs --arg-file=options.txt lsEquivalent to
ls -l -a file1.txt file2.txt. -
Specify the maximum number of arguments (
-n): (Already covered above, but important).echo "a b c d e" | xargs -n 2 echoOutputs:
a b c d e -
Specify the delimiter (
-d): (Already covered above, but important).echo "one,two,three" | xargs -d ',' echoOutputs:
one two three
Common Patterns
-
Find and delete files with spaces in their names:
find . -type f -name "* *" -print0 | xargs -0 rm -
Find and move files to a directory:
find . -name "*.tmp" -print0 | xargs -0 -I {} mv {} /path/to/archive/ -
Count lines in multiple files found by
grep:grep -l "pattern" *.log | xargs -I {} wc -l {} -
Process files in parallel using
findandxargs:find . -name "*.png" -print0 | xargs -0 -P 8 -I {} convert {} -quality 85 {}(Converts PNGs to a lower quality, overwriting originals, in parallel).
-
Execute a command with arguments from a file, one argument per line:
# list_of_ips.txt contains: # 192.168.1.1 # 192.168.1.2 xargs -a list_of_ips.txt -I {} ping -c 1 {} -
Using
xargsas a simple command builder (less common thanfind):echo "user1 user2" | xargs -I {} sudo userdel {}Deletes
user1anduser2usingsudo userdel.
Gotchas
-
Whitespace and Special Characters: The biggest pitfall. By default,
xargssplits input by whitespace and treats quotes and backslashes specially. This can break commands if your input items (like filenames) contain spaces or special characters. Always usefind ... -print0 | xargs -0 ...when dealing with filenames. -
-Lvs-n:-L 1reads one line at a time and passes it as arguments.-n 1reads one item at a time and passes it as arguments. If a line has multiple items,-L 1might pass the whole line, while-n 1would pass only the first item. -
Command Execution:
xargsappends the arguments to the command you provide. If you want to insert arguments in the middle, you must use-I. -
Empty Input: If
xargsreceives no input, it will not run the command by default. Use-r(or--no-run-if-empty) if you want to prevent execution when input is empty. -
Shell Interpretation:
xargsdoes not interpret shell metacharacters like*,?,~, etc., in the arguments it passes. If you need shell expansion, you often need to useeval(carefully!) or structure your command differently. For example,echo "*.txt" | xargs lswill list a file named "*.txt", not all text files. Usels *.txtdirectly, orfind . -name "*.txt" -exec ls {} \;orfind . -name "*.txt" -print0 | xargs -0 ls. -
Argument List Too Long: While
xargsis designed to mitigate this by running commands multiple times, extremely long argument lists combined with other command-line options might still hit system limits. The-sflag can help control the maximum length, but it’s often better to rely on-nor-Land potentially-Pfor parallel processing.