LUNAROPS · OPERATIONAL UPLINK 100% UPTIME 1,247d POSTS 893 JEFF.MOON@LUNAROPS.DEV UTC --:--:--

xargs: Building Commands from Input

xargscliparallelscripting

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

Handling Empty Input

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