dotlinux blog

xargs for Beginners with Examples

If you’ve spent any time working in the Unix/Linux command line, you’ve likely encountered situations where you want to pass the output of one command as arguments to another. For example, you might use find to locate files and then want to delete, copy, or process those files with another tool like rm or cp. But here’s the catch: many commands (like rm, cp, or mkdir) don’t accept input directly from a pipe (|). Instead, they require arguments to be passed directly on the command line.

This is where xargs shines. Short for "execute arguments," xargs is a powerful command-line utility that bridges this gap by converting standard input (like the output of another command) into command-line arguments for other programs. Whether you’re a beginner or looking to level up your CLI skills, understanding xargs will save you time and make your workflows more efficient.

2026-01

Table of Contents#

What is xargs?#

xargs is a command-line tool that reads items from standard input (typically piped from another command) and passes them as arguments to a specified command. It’s designed to solve a common problem: many Unix commands (e.g., rm, cp, mkdir) expect arguments to be provided directly on the command line, not via standard input (stdin).

For example, if you run ls *.txt | rm, it won’t work because rm doesn’t read filenames from stdin. Instead, you need to pass the filenames as arguments: rm file1.txt file2.txt. xargs fixes this by taking the output of ls *.txt and converting it into arguments for rm.

How xargs Works: The Basics#

The workflow with xargs typically looks like this:
command1 | xargs command2

Here’s what happens step-by-step:

  1. command1 generates output (e.g., a list of filenames, words, or numbers) and sends it to stdout.
  2. The pipe (|) redirects this output to xargs as stdin.
  3. xargs parses the input, splits it into "items" (by default, split on whitespace or newlines), and converts these items into command-line arguments.
  4. xargs then runs command2 with these arguments appended to it.

By default, if no command2 is specified, xargs uses /bin/echo, so echo "hello world" | xargs is equivalent to echo hello world.

Basic Syntax#

The most common form of xargs is:

command1 | xargs [options] command2  
  • command1: The command generating input (e.g., find, echo, ls).
  • options: Optional flags to customize xargs behavior (covered later).
  • command2: The command that will receive the arguments from xargs (e.g., rm, cp, wc).

Common Use Cases with Examples#

Let’s dive into practical examples to see xargs in action. These are scenarios you’ll encounter daily as a CLI user.

Example 1: Listing Files with Details#

Suppose you have a list of filenames and want to view their details (permissions, size, etc.) with ls -l. Instead of typing ls -l file1.txt file2.txt manually, use xargs to pass the filenames as arguments to ls -l:

echo "file1.txt file2.txt file3.txt" | xargs ls -l  

Output:

-rw-r--r-- 1 user user 0 Oct 1 10:00 file1.txt  
-rw-r--r-- 1 user user 0 Oct 1 10:00 file2.txt  
-rw-r--r-- 1 user user 0 Oct 1 10:00 file3.txt  

Here, echo generates the filenames, xargs passes them to ls -l, and ls -l lists details for all three files.

Example 2: Deleting Files Safely#

A classic use case for xargs is deleting files found by find. For example, to delete all .tmp files in the current directory and subdirectories:

find . -name "*.tmp" | xargs rm  

How it works:

  • find . -name "*.tmp" locates all files ending with .tmp.
  • xargs passes these filenames to rm, which deletes them.

⚠️ Warning: If filenames contain spaces or newlines (e.g., my file.tmp), this command will fail because xargs splits input on whitespace by default. To handle this, use the -0 flag with find -print0 (covered in Advanced Options).

Example 3: Copying Files to a Directory#

Suppose you want to copy all .jpg images from your current folder to a photos directory in your home. cp requires a source and destination, so we use xargs -I to replace a placeholder with each input item:

find . -name "*.jpg" | xargs -I {} cp {} ~/photos/  

Breakdown:

  • -I {} tells xargs to replace {} with each input item (e.g., ./vacation.jpg).
  • cp {} ~/photos/ becomes cp ./vacation.jpg ~/photos/ for each .jpg file found.

The placeholder {} can be any string (e.g., %, FILE), but {} is convention.

Example 4: Counting Lines in Multiple Files#

To count the total number of lines across all .txt files in a project, combine find with xargs and wc -l (word count, lines):

find . -name "*.txt" | xargs wc -l  

Output:

  10 ./notes.txt  
  25 ./draft.txt  
  35 total  

xargs passes all .txt filenames to wc -l, which sums their lines.

Example 5: Creating Directories#

Quickly create multiple directories by passing names to mkdir via xargs:

echo "docs logs backups" | xargs mkdir  

This creates three directories: docs, logs, and backups.

⚠️ Note: If directory names contain spaces (e.g., my docs), enclose them in quotes and use xargs -d '\n' to split on newlines instead of spaces:

echo -e "my docs\nlogs\nbackups" | xargs -d '\n' mkdir  

Example 6: Limiting Arguments Per Command#

By default, xargs passes all input items to a single command2. Use -n N to run command2 multiple times, with N arguments per run.

For example, to print 2 items per line:

echo "a b c d e" | xargs -n 2 echo  

Output:

a b  
c d  
e  

Here, echo runs 3 times: with a b, c d, and e.

Advanced xargs Options#

These flags unlock xargs’s full potential, especially for edge cases like filenames with spaces or prompting before risky commands.

-0: Handle Filenames with Spaces/Newlines#

The -0 (null-terminated) flag tells xargs to read input items separated by null bytes (\0) instead of whitespace. Pair this with find -print0 to safely handle filenames with spaces, newlines, or special characters:

find . -name "*.tmp" -print0 | xargs -0 rm  
  • find -print0 outputs filenames separated by \0 (not newlines).
  • xargs -0 reads these null-separated filenames, avoiding splits on spaces.

-I: Replace Strings for Flexible Command Execution#

As seen in Example 3, -I <placeholder> replaces <placeholder> with each input item. This is critical for commands like cp or mv that need input items in specific positions.

Example: Rename all .txt files to .md (Markdown):

find . -name "*.txt" | xargs -I {} mv {} {}.md  

Here, {} is replaced with ./notes.txt, making the command mv ./notes.txt ./notes.txt.md.

-n: Control Number of Arguments Per Command#

As in Example 6, -n N limits command2 to N arguments per execution. Useful for commands that can’t handle too many arguments at once.

Example: Ping 2 servers at a time:

echo "google.com github.com example.com" | xargs -n 2 ping -c 1  

This runs ping -c 1 google.com github.com, then ping -c 1 example.com.

-p: Prompt Before Execution#

Use -p to confirm commands before running them (great for destructive actions like rm):

find . -name "*.tmp" | xargs -p rm  

Output:

rm ./old.tmp ./junk.tmp ?...y  

Type y to proceed, or n to cancel.

-t: Print Commands Before Execution#

The -t flag prints the command xargs is about to run, helping debug complex pipelines:

echo "a b c" | xargs -t -n 2 echo  

Output:

echo a b  
a b  
echo c  
c  

Here, -t shows echo a b and echo c before executing them.

Tips and Best Practices#

  1. Handle Spaces in Filenames: Always use find -print0 | xargs -0 instead of raw xargs to avoid issues with spaces, newlines, or special characters in filenames.
  2. Test First with echo: If you’re unsure what xargs will run, pipe to echo first:
    find . -name "*.txt" | xargs echo rm  # Dry run to preview deletions  
  3. Use -p for Destructive Commands: Add -p to rm, mv, or rmdir to avoid accidental data loss.
  4. Prefer -I for Commands with Multiple Arguments: Tools like cp or mv need source/destination pairs; -I lets you place input items exactly where needed.
  5. Limit Arguments with -n: For commands that can’t handle too many arguments (e.g., grep on thousands of files), use -n to split the workload.

Conclusion#

xargs is a Swiss Army knife for the command line, turning the output of one command into actionable arguments for another. From deleting files to copying photos or counting lines, it simplifies workflows that would otherwise require tedious manual input.

By mastering basics like xargs rm and advanced flags like -0 and -I, you’ll write more efficient, robust CLI pipelines. Remember to test with -t or -p first, and always handle filenames with spaces using find -print0 | xargs -0.

References#