xargs reads items from input and executes a command with those items as arguments. It’s the glue that connects commands together.
Basic Usage
1
2
3
4
5
|
# Simple example
echo "file1 file2 file3" | xargs rm
# Equivalent to:
rm file1 file2 file3
|
From find
The most common pairing:
1
2
3
4
5
|
# Delete all .tmp files
find . -name "*.tmp" | xargs rm
# More safely with -print0 and -0
find . -name "*.tmp" -print0 | xargs -0 rm
|
The -print0 and -0 handle filenames with spaces.
One Argument at a Time
1
2
|
# Process each file separately
find . -name "*.txt" | xargs -n 1 wc -l
|
Output:
10 ./file1.txt
20 ./file2.txt
15 ./file3.txt
Placeholder Replacement
Use -I to place arguments anywhere:
1
2
3
4
5
|
# Rename files
ls *.txt | xargs -I {} mv {} {}.bak
# Copy to directory
find . -name "*.jpg" | xargs -I {} cp {} /backup/
|
Parallel Execution
Speed up with multiple processes:
1
2
3
4
5
|
# Run 4 processes in parallel
find . -name "*.png" | xargs -P 4 -I {} convert {} {}.jpg
# Compress files in parallel
ls *.log | xargs -P 4 gzip
|
Confirmation
Ask before each execution:
1
2
|
echo "file1 file2 file3" | xargs -p rm
# rm file1 file2 file3 ?...y
|
Limiting Arguments
1
2
3
4
5
|
# Max 2 arguments per command
echo "1 2 3 4 5" | xargs -n 2 echo
# 1 2
# 3 4
# 5
|
1
2
3
4
|
# Don't run if input is empty
echo "" | xargs -r rm # Does nothing
# Without -r would error: rm with no arguments
|
Practical Examples
Find and grep
1
2
3
4
5
|
# Search for pattern in specific files
find . -name "*.py" | xargs grep "import requests"
# With filenames
find . -name "*.py" | xargs grep -l "import requests"
|
Batch Operations
1
2
3
4
5
|
# Convert images
ls *.png | xargs -I {} convert {} -resize 50% thumb_{}
# Compress old logs
find /var/log -name "*.log" -mtime +30 | xargs gzip
|
Parallel Downloads
1
2
|
# Download multiple files
cat urls.txt | xargs -P 5 -I {} curl -O {}
|
Kill Processes
1
2
3
4
5
|
# Kill all node processes
pgrep node | xargs kill
# More safely
pgrep -f "node.*server" | xargs -r kill
|
Git Operations
1
2
3
4
5
|
# Add all modified files
git status -s | awk '{print $2}' | xargs git add
# Remove deleted files
git ls-files --deleted | xargs git rm
|
File Statistics
1
2
3
4
5
|
# Total size of matched files
find . -name "*.log" | xargs du -ch | tail -1
# Line counts
find . -name "*.py" | xargs wc -l | tail -1
|
Install Packages
1
2
3
4
5
|
# Install from list
cat packages.txt | xargs apt install -y
# pip packages
cat requirements.txt | xargs pip install
|
Advanced Options
Custom Delimiter
1
2
3
|
# Comma-separated
echo "a,b,c" | xargs -d ',' echo
# a b c
|
Max Command Length
1
2
|
# Split into multiple commands if too long
find . -name "*.txt" | xargs -s 1024 cat
|
Dry Run
1
2
|
# Print commands without executing
find . -name "*.tmp" | xargs echo rm
|
Comparison: xargs vs -exec
1
2
3
4
5
6
7
8
|
# find with -exec (one command per file)
find . -name "*.txt" -exec grep "pattern" {} \;
# find with xargs (batched, faster)
find . -name "*.txt" | xargs grep "pattern"
# find with -exec + (batched like xargs)
find . -name "*.txt" -exec grep "pattern" {} +
|
Error Handling
1
2
|
# Stop on first error
find . -name "*.sh" | xargs -P 4 --halt=now,fail=1 sh -c 'chmod +x "$0" && ./"$0"'
|
Cheat Sheet
1
2
3
4
5
6
7
8
|
xargs # Build command from input
xargs -n 1 # One argument per command
xargs -P 4 # 4 parallel processes
xargs -I {} # Placeholder for argument
xargs -0 # Null-delimited input
xargs -r # No-run if empty
xargs -p # Prompt before each
find . | xargs cmd # Common pattern
|
xargs turns any list into command arguments. Combined with find, grep, and other tools, it enables powerful batch operations.
Comments