xargs Command in Linux â Build and Execute Commands
In this tutorial, you'll learn about xargs command in linux. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
xargs reads items from standard input (or a file) and executes a command with those items as arguments. It bridges the gap between commands that output lists and commands that need arguments â a critical tool for batch processing and automation.
What You'll Learn
By the end of this tutorial, you'll know how to use xargs for basic argument building, control delimiters, use placeholders, limit arguments per command, run tasks in parallel, handle null-separated input from find, simulate commands with dry-run, and handle special characters safely.
Why xargs Matters
Many Linux commands output lists (find, grep -l, ls), but few accept input via pipe directly. xargs converts that output into command-line arguments. Durga Antivirus Pro uses xargs to batch-scan files found by find, and DodaZIP uses it to compress files in parallel across multiple CPU cores.
xargs Learning Path
flowchart LR A[find Command] --> B[xargs Command
You are here] B --> C[Shell Scripting] C --> D[Process Management] D --> E[Automation] style B fill:#f90,color:#fff
Prerequisites: Know find and grep â xargs is most useful when combined with them.
Syntax Overview
command | xargs [options] [command [initial-arguments]]
| Option | Description |
|---|---|
-n N |
Max number of arguments per command |
-I placeholder |
Replace string in command with input |
-P N |
Run up to N processes in parallel |
-d delim |
Use custom delimiter (not whitespace) |
-0 |
Null-delimited input (with find -print0) |
-t |
Print command before executing (trace) |
-p |
Prompt before executing each command |
-r |
Don't run if input is empty (GNU default) |
10 Practical Examples
1. Basic xargs â Convert Input to Arguments
Remove all .tmp files listed by find:
echo "file1.tmp file2.tmp file3.tmp" | xargs rm
No output if successful. Check:
echo "file1.tmp file2.tmp file3.tmp" | xargs ls -la 2>&1 | head -3
ls: cannot access 'file1.tmp': No such file or directory
ls: cannot access 'file2.tmp': No such file or directory
2. Custom Delimiter
Process a comma-separated list:
echo "apple,banana,cherry,date" | xargs -d ',' -n 1 echo "Fruit:"
Fruit: apple
Fruit: banana
Fruit: cherry
Fruit: date
3. Placeholder with -I
Use {} as a placeholder for where the input appears in the command:
echo "data.txt" | xargs -I {} cp {} /backup/{}.bak
This copies data.txt to /backup/data.txt.bak.
Move files into a directory:
echo "file1 file2" | xargs -I {} mv {} /target/dir/
4. Limit Arguments per Command (-n)
wc -l on each file individually:
echo -e "file1.txt\nfile2.txt\nfile3.txt" | xargs -n 1 wc -l
If file1.txt has 5 lines, file2.txt has 3, file3.txt has 8:
5 file1.txt
3 file2.txt
8 file3.txt
Without -n, xargs passes all files at once:
echo -e "file1.txt\nfile2.txt\nfile3.txt" | xargs wc -l
5 file1.txt
3 file2.txt
8 file3.txt
16 total
5. Parallel Execution (-P)
Compress all .log files in parallel (4 at a time):
find /var/log -name "*.log" -type f | xargs -P 4 -I {} gzip {}
No direct output, but processes run simultaneously. Verify:
ls /var/log/*.log.gz 2>/dev/null | head -3
/var/log/syslog.gz
/var/log/kern.log.gz
/var/log/auth.log.gz
6. Null Delimiter with find
Safe handling of filenames with spaces:
find /home -name "*.bak" -type f -print0 | xargs -0 rm
The -print0 flag uses null characters (not newlines) to separate filenames. -0 tells xargs to expect null-delimited input. This is essential when filenames contain spaces, tabs, or newlines.
7. Combining with find
Find all Python files and count lines:
find /home/projects -name "*.py" -type f | xargs wc -l
125 /home/projects/src/main.py
42 /home/projects/src/utils.py
15 /home/projects/tests/test_main.py
182 total
Find files containing "TODO" and edit them:
grep -rl "TODO" /home/projects/ | xargs sed -i 's/TODO/FIXME/g'
8. Dry Run / Trace Mode
Print each command before executing:
echo "file1 file2 file3" | xargs -t rm
rm file1 file2 file3
The -t flag shows what command will run before executing it. Use this for safety when testing.
9. Interactive Prompt
Prompt before each execution:
find /tmp -name "*.tmp" | xargs -p rm
rm /tmp/abc.tmp /tmp/xyz.tmp ?...y
10. Handle Special Characters
Filenames with spaces require special handling:
# Dangerous: will fail on "My File.txt"
find /home -name "*.txt" | xargs rm
# Safe: handles spaces correctly
find /home -name "*.txt" -print0 | xargs -0 rm
Common Use Cases
Delete Files Older Than 30 Days
find /var/log -name "*.log" -mtime +30 -print0 | xargs -0 rm
Change File Extensions
find . -name "*.html" -print0 | xargs -0 -I {} mv {} {}.bak
Count Lines in All Source Files
find . \( -name "*.py" -o -name "*.js" \) -print0 | xargs -0 wc -l
Parallel Compression
find /var/log -name "*.log" -mtime +1 -print0 | xargs -0 -P $(nproc) gzip
Common Mistakes
1. Not Using -0 with find -print0
If filenames contain spaces, tabs, or newlines, xargs splits them incorrectly. Always pair find -print0 with xargs -0.
2. Forgetting That xargs Appends Arguments by Default
xargs cmd runs cmd input1 input2 .... Use -I to place input at a specific position in the command.
3. Running Dangerous Commands Without Testing
find . -name "*.log" | xargs rm could delete files you didn't intend. Use -p or -t first to verify.
4. Command-Line Length Limits
Without -n, xargs packs as many arguments as possible into one command. Very large lists may exceed the system's maximum argument length. Use -n 100 to limit batch size.
Practice Questions
1. How do you safely pass filenames with spaces from find to xargs?
Use find ... -print0 | xargs -0 command
2. What does -n 1 do in xargs?
It limits each invocation of the command to exactly 1 argument from input.
3. How do you use xargs to run commands in parallel?
Use -P N where N is the number of parallel processes. Example: xargs -P 4 -I {} cmd {}
4. What's the difference between xargs -t and xargs -p?
-t prints each command before executing (no confirmation). -p prints and asks for confirmation before each execution.
5. Challenge: Write a one-liner using find and xargs that finds all .log files, compresses them with gzip, using 4 parallel processes, safely handling filenames.
find /var/log -name "*.log" -type f -print0 | xargs -0 -P 4 -I {} gzip {}
Mini Project: Batch File Processor
#!/bin/bash
# batch_process.sh â Process files matching criteria
# Usage: ./batch_process.sh /path/to/scan
SCAN_DIR="${1:?Usage: $0 /path/to/scan}"
ACTION="${2:-count}" # count, compress, backup
case "$ACTION" in
count)
echo "Counting lines in source files..."
find "$SCAN_DIR" \( -name "*.py" -o -name "*.js" -o -name "*.sh" \) \
-type f -print0 | xargs -0 wc -l
;;
compress)
echo "Compressing large files (>10MB)..."
find "$SCAN_DIR" -type f -size +10M -print0 | \
xargs -0 -P "$(nproc)" -I {} gzip -v {} 2>/dev/null
echo "Done."
;;
backup)
BACKUP_DIR="/tmp/backup-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
find "$SCAN_DIR" -type f -mtime -1 -print0 | \
xargs -0 -I {} cp {} "$BACKUP_DIR"
echo "Backed up to: $BACKUP_DIR"
echo "Files: $(ls "$BACKUP_DIR" | wc -l)"
;;
esac
Expected output (count action):
Counting lines in source files...
125 /home/projects/src/main.py
42 /home/projects/src/utils.py
15 /home/projects/tests/test_main.py
30 /home/projects/scripts/deploy.sh
212 total
FAQ
What's Next
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro