xargs: Turning Output into Arguments

Many commands output lists. Many commands need arguments. xargs connects them. It reads input and runs a command with that input as arguments. Basic Usage 1 2 3 4 5 6 7 8 9 # Without xargs (doesn't work) find . -name "*.txt" | rm # rm doesn't read stdin # With xargs (works) find . -name "*.txt" | xargs rm # What's happening echo "file1 file2 file3" | xargs rm # Becomes: rm file1 file2 file3 Input Handling 1 2 3 4 5 6 7 8 9 10 11 12 13 # Default: split on whitespace echo "a b c" | xargs echo # Output: a b c # One item per line echo -e "a\nb\nc" | xargs echo # Output: a b c # Handle spaces in filenames (-0 with null delimiter) find . -name "*.txt" -print0 | xargs -0 rm # Treat each line as one argument cat list.txt | xargs -d '\n' command Argument Placement 1 2 3 4 5 6 7 8 9 10 # Default: append to end echo "file.txt" | xargs wc -l # Becomes: wc -l file.txt # Custom placement with -I echo "file.txt" | xargs -I {} cp {} {}.bak # Becomes: cp file.txt file.txt.bak # Multiple uses of placeholder echo "file.txt" | xargs -I {} sh -c 'echo "Processing {}"; wc -l {}' Limiting Arguments 1 2 3 4 5 6 7 8 9 10 11 12 13 # One argument per command execution find . -name "*.txt" | xargs -n 1 rm # Runs: rm file1.txt, rm file2.txt, rm file3.txt (separately) # Two arguments per execution echo "a b c d e f" | xargs -n 2 echo # Output: # a b # c d # e f # Limit by size (bytes) echo "a b c d e f" | xargs -s 10 echo Parallel Execution 1 2 3 4 5 6 7 8 # Run 4 processes in parallel find . -name "*.jpg" | xargs -P 4 -I {} convert {} -resize 800x600 {}.resized.jpg # All available CPUs find . -name "*.log" | xargs -P 0 gzip # Combined with -n cat urls.txt | xargs -n 1 -P 10 curl -O Confirmation (-p) and Verbose (-t) 1 2 3 4 5 # Ask before each execution find . -name "*.bak" | xargs -p rm # Show command before running find . -name "*.txt" | xargs -t wc -l Handling Empty Input 1 2 3 4 # Don't run if no input find . -name "*.missing" | xargs --no-run-if-empty rm # Short form: find . -name "*.missing" | xargs -r rm Practical Examples Bulk File Operations 1 2 3 4 5 6 7 8 9 10 11 # Delete files matching pattern find . -name "*.tmp" -print0 | xargs -0 rm -f # Move files to directory find . -name "*.jpg" -print0 | xargs -0 -I {} mv {} ./images/ # Change permissions find . -type f -name "*.sh" | xargs chmod +x # Compress multiple files find . -name "*.log" -mtime +7 | xargs gzip Search and Process 1 2 3 4 5 6 7 8 # Search in found files find . -name "*.py" | xargs grep "import os" # Count lines in all matching files find . -name "*.js" | xargs wc -l # Replace text in multiple files find . -name "*.txt" | xargs sed -i 's/old/new/g' Git Operations 1 2 3 4 5 6 7 8 # Add specific files git status --short | awk '{print $2}' | xargs git add # Remove deleted files from tracking git ls-files --deleted | xargs git rm # Checkout specific files echo "file1.txt file2.txt" | xargs git checkout -- Download Multiple URLs 1 2 3 4 5 6 7 8 # Download sequentially cat urls.txt | xargs -n 1 curl -O # Download in parallel (10 at a time) cat urls.txt | xargs -n 1 -P 10 curl -O # wget version cat urls.txt | xargs -n 1 -P 5 wget -q Docker Operations 1 2 3 4 5 6 7 8 9 10 11 # Stop all containers docker ps -q | xargs docker stop # Remove all stopped containers docker ps -aq | xargs docker rm # Remove images by pattern docker images | grep "none" | awk '{print $3}' | xargs docker rmi # Pull multiple images echo "nginx redis postgres" | xargs -n 1 docker pull Process Management 1 2 3 4 5 6 7 8 # Kill processes by name pgrep -f "pattern" | xargs kill # Kill processes by name (safer) pgrep -f "my-app" | xargs -r kill -9 # Send signal to multiple PIDs cat pids.txt | xargs kill -HUP Package Management 1 2 3 4 5 6 7 8 # Install multiple packages echo "vim git curl wget" | xargs sudo apt install -y # Uninstall packages from list cat remove.txt | xargs sudo apt remove -y # pip install from list cat requirements.txt | xargs -n 1 pip install Combining with Other Tools With find 1 2 3 4 5 # Process found files find . -name "*.md" -print0 | xargs -0 -I {} pandoc {} -o {}.html # Archive old files find /var/log -name "*.log" -mtime +30 -print0 | xargs -0 tar -czvf old-logs.tar.gz With grep 1 2 3 4 5 # Files containing pattern -> process grep -l "TODO" *.py | xargs -I {} echo "File with TODOs: {}" # Extract matches and process grep -oh "https://[^ ]*" urls.txt | xargs -n 1 -P 5 curl -sI | grep "HTTP" With awk 1 2 3 4 5 # Select column and process ps aux | awk '$3 > 50 {print $2}' | xargs kill # Format output for xargs cat data.csv | awk -F, '{print $1}' | xargs -I {} echo "ID: {}" Error Handling 1 2 3 4 5 6 7 8 9 # Continue on errors find . -name "*.txt" | xargs -I {} sh -c 'command {} || true' # Stop on first error (default behavior) find . -name "*.txt" | xargs command # Exit codes echo "a b c" | xargs false echo $? # Non-zero Performance Comparison 1 2 3 4 5 6 7 8 # Slow: one process per file for f in *.txt; do wc -l "$f"; done # Faster: batch arguments ls *.txt | xargs wc -l # Fastest: parallel execution ls *.txt | xargs -P 4 -n 10 wc -l GNU Parallel Alternative For complex parallel jobs, GNU Parallel offers more features: ...

February 24, 2026 ยท 6 min ยท 1237 words ยท Rob Washington