| |

LFCS 27 ๐Ÿง xargs โ€” Building Argument Lists

Some commands read their input from the standard input. The grep, the sed, the awk, and the sort are the line-oriented, and the pipe is the natural. Other commands expect the arguments on the command line. The rm, the cp, the mv, the mkdir, and the chmod take the file names as the arguments, and they do not read the standard input. The echo 'file.txt' | rm does nothing, because the rm does not read the pipe. The xargs is the bridge. It reads the items from the standard input and runs the command with the items as the arguments. The find . -name '*.log' | xargs rm finds the log files and removes them, and the xargs converts the pipe to the argument list. The xargs is the standard tool for the pipelines that end in the commands that expect the arguments, and the LFCS exam tests it as part of the “Use streams, pipes, and redirects” objective.

The xargs has the important options. The -0 reads the null-separated input, and the -print0 from the find produces it. The -n limits the number of the arguments per command, and the -I {} replaces the placeholder in the command. The -P runs the commands in the parallel, and the -t prints the command before the execution. The -r (the --no-run-if-empty) does not run the command when the input is the empty, and it is the GNU extension. The -d sets the custom delimiter, and the -L limits the lines per command.

The xargs has the specific behavior. It reads the items, the whitespace-separated by default, and it builds the argument list. The default command is the echo, and the xargs alone prints the items. The xargs runs the command once with the many arguments when possible, and the -n forces the smaller batches. The xargs is the standard input to the argument conversion, and it is the complement to the pipe.

This chapter covers three areas. First, why the xargs exists โ€” the argument-list problem and the pipe-to-argument bridge. Second, the syntax and the options โ€” the -0, the -n, the -I {}, the -P, the -t, and the -r. Third, the common patterns โ€” the find with the xargs, the parallel processing, the placeholder, and the safety. The chapter ends with a complete example session, a quick reference, best practices, common pitfalls, real-world examples, and diagrams showing the xargs flow.

Key point: The xargs reads the items from the standard input and runs the command with the items as the arguments. The -0 reads the null-separated input, and the find -print0 produces it. The -n limits the arguments per command, the -I {} replaces the placeholder, the -P runs in the parallel, and the -r does not run on the empty input. The xargs is the bridge between the pipe and the commands that expect the arguments.


Why xargs exists

The argument-list problem. The commands have the two kinds of the input. The filters โ€” the grep, the sed, the awk โ€” read the standard input line by line. The utilities โ€” the rm, the cp, the mv โ€” take the arguments on the command line. The echo 'file.txt' | rm does not work, because the rm ignores the standard input. The xargs reads the standard input and passes the items as the arguments: the echo 'file.txt' | xargs rm works, because the xargs converts the pipe to the rm file.txt command.

The command-line-length problem. The command line has the length limit, the ARG_MAX. The rm $(find . -name '*.log') may exceed the limit and fail with the “Argument list too long” error. The xargs splits the items into the batches and runs the command multiple times, and the limit is the respected. The -n controls the batch size.

The null-separated problem. The file names can contain the spaces, the newlines, and the quotes. The find . -name '*.log' | xargs rm splits the names on the whitespace, and the file name with the space is the broken. The -print0 from the find and the -0 from the xargs use the null character as the separator, and the file names are the preserved. The -0 is the critical for the safe.

The parallel problem. The xargs can run the commands in the parallel with the -P. The find . -name '*.jpg' | xargs -P 4 -n 1 convert runs the four conversions at once, and the wall-clock time is the reduced. The parallel is the advanced, and it is the powerful for the batch processing.

The placeholder problem. The command sometimes needs the item in the specific position, not the end. The -I {} replaces the {} in the command with the item: the find . -name '*.txt' | xargs -I {} mv {} {}.bak renames the each file. The -I also implies the -L 1, so the command runs once per item.

The trade-off. The xargs is the powerful and the subtle. The default whitespace splitting is the unsafe for the file names, and the -0 is the fix. The -I is the convenient and the slower, because it runs the command once per item. The trade-off is between the batch efficiency and the per-item control.


a. The basic xargs syntax

The xargs reads the standard input and runs the command with the items as the arguments.

echo 'file1 file2 file3' | xargs rm
# the equivalent: rm file1 file2 file3

echo 'file1 file2 file3' | xargs -n 1 ls -l
# the ls -l file1; the ls -l file2; the ls -l file3

The default command is the echo:

echo 'file1 file2' | xargs
# the file1 file2

The xargs alone prints the items, and it is the way to see the parsing.

The -n. The -n limits the arguments per command:

echo 'a b c d e f' | xargs -n 2 echo
# the echo a b; the echo c d; the echo e f

The -n 1 runs the command once per item, and the -n 2 runs it with the two items.

The -0. The -0 reads the null-separated input:

find . -name '*.log' -print0 | xargs -0 rm

The -print0 from the find produces the null-separated, and the -0 from the xargs reads it. The file names with the spaces are the preserved.

The -I {}. The -I replaces the placeholder:

find . -name '*.txt' | xargs -I {} mv {} {}.bak
# the mv file1.txt file1.txt.bak; the mv file2.txt file2.txt.bak

The {} is the placeholder, and the xargs replaces it with the item. The -I implies the -L 1, so the command runs once per item.

The -P. The -P runs the commands in the parallel:

find . -name '*.jpg' -print0 | xargs -0 -P 4 -n 1 convert
# the four convert processes at once

The -P 4 runs the four commands in the parallel, and the -n 1 runs the one item per command.

The -t. The -t prints the command before the execution:

echo 'file1 file2' | xargs -t rm
# the rm file1 file2
# the (the rm runs)

The -t is the verbose, and it shows the command.

The -r. The -r does not run the command when the input is the empty:

echo '' | xargs -r rm
# the rm is NOT run

echo '' | xargs rm
# the rm is run with the no arguments (the error)

The -r is the GNU extension, and it is the safety for the empty input.

The -d. The -d sets the custom delimiter:

echo 'a:b:c' | xargs -d: echo
# the echo a b c

The -d: uses the colon as the delimiter, and the -d '\n' uses the newline.

The -L. The -L limits the lines per command:

printf 'a\nb\nc\n' | xargs -L 1 echo
# the echo a; the echo b; the echo c

The -L 1 runs the command once per line, and the -L 2 runs it with the two lines.


b. The common patterns

The find and the xargs. The find produces the file list, and the xargs runs the command.

find . -name '*.log' -print0 | xargs -0 rm
find . -type f -size +100M -print0 | xargs -0 ls -lh
find . -name '*.tmp' -print0 | xargs -0 -r rm

The -print0 and the -0 are the safe pair, and the -r is the empty input guard.

The parallel processing. The -P runs the commands in the parallel:

find . -name '*.jpg' -print0 | xargs -0 -P 4 -n 1 convert -resize 50% {}

The -P 4 is the four parallel, and the -n 1 is the one item per command.

The placeholder. The -I {} replaces the placeholder:

find . -name '*.txt' | xargs -I {} cp {} /backup/{}
cat file.txt | xargs -I {} echo 'The line: {}'

The -I runs the command once per item, and the placeholder is the item.

The multiple arguments. The -n with the multiple items:

seq 1 10 | xargs -n 3 echo
# the echo 1 2 3; the echo 4 5 6; the echo 7 8 9; the echo 10

The sh -c. The xargs with the sh -c for the complex commands:

find . -name '*.log' -print0 | xargs -0 -I {} sh -c 'echo "Processing: $1"; gzip "$1"' _ {}

The _ is the $0, and the {} is the $1.

The dry run. The -t with the echo for the dry run:

find . -name '*.log' -print0 | xargs -0 -t echo

The -t echo prints the command without the executing.

The prompt. The -p prompts before the each command:

find . -name '*.log' -print0 | xargs -0 -p rm

The -p is the interactive, and it is the dangerous-safe.

The -a. The -a reads from the file:

xargs -a filelist.txt rm

The -a reads the items from the file instead of the standard input.

The -E. The -E sets the end-of-file string:

echo 'a b EOF c' | xargs -E EOF echo
# the echo a b

The -E EOF stops at the EOF marker.


c. The safety and the pitfalls

The whitespace splitting. The default xargs splits on the whitespace, and the file name with the space is the broken:

# โŒ The unsafe
find . -name '*.log' | xargs rm
# The "my file.log" is split into the "my" and the "file.log"

The -print0 and the -0 are the fix.

The empty input. The xargs with the empty input runs the command with the no arguments, and the command may do the unexpected:

# โŒ The dangerous
echo '' | xargs rm
# the rm with the no arguments

The -r is the guard, and it is the GNU.

The -I and the -n. The -I implies the -L 1, and it conflicts with the -n:

# โŒ The conflict
find . -name '*.log' | xargs -I {} -n 2 rm {}
# The -I overrides the -n

The use of the one or the other.

The command injection. The xargs with the untrusted input is the risk, because the items become the arguments:

# โŒ The risky
echo 'file; rm -rf /' | xargs sh -c

The sh -c with the untrusted input is the danger, and the validation is the requirement.

The -P and the output. The -P runs the commands in the parallel, and the output is the interleaved:

find . -name '*.log' -print0 | xargs -0 -P 4 grep 'error'
# The output is the interleaved from the four greps

The --output or the separate files are the fix.

The ARG_MAX. The xargs respects the ARG_MAX, and the -n controls the batch:

getconf ARG_MAX
# the 2097152 (the 2MB)

The xargs splits the long lists automatically.

The -0 with the non-null. The -0 expects the null-separated, and the newline-separated input with the -0 is the single item:

# โŒ The wrong
echo 'file1 file2' | xargs -0 rm
# the "file1 file2" is the single item

The -0 requires the -print0 or the null-separated input.


Complete Example Session

# ============================================
# PART 1: THE BASIC xargs
# ============================================

echo 'file1 file2 file3' | xargs rm
# the rm file1 file2 file3

echo 'a b c d e f' | xargs -n 2 echo
# the echo a b; the echo c d; the echo e f


# ============================================
# PART 2: THE NULL SEPARATOR
# ============================================

find . -name '*.log' -print0 | xargs -0 rm


# ============================================
# PART 3: THE PLACEHOLDER
# ============================================

find . -name '*.txt' | xargs -I {} mv {} {}.bak


# ============================================
# PART 4: THE PARALLEL
# ============================================

find . -name '*.jpg' -print0 | xargs -0 -P 4 -n 1 convert -resize 50%


# ============================================
# PART 5: THE VERBOSE
# ============================================

echo 'file1 file2' | xargs -t rm
# the rm file1 file2
# the (the rm runs)


# ============================================
# PART 6: THE EMPTY INPUT GUARD
# ============================================

echo '' | xargs -r rm
# the rm is NOT run


# ============================================
# PART 7: THE CUSTOM DELIMITER
# ============================================

echo 'a:b:c' | xargs -d: echo
# the echo a b c


# ============================================
# PART 8: THE LINES PER COMMAND
# ============================================

printf 'a\nb\nc\n' | xargs -L 1 echo
# the echo a; the echo b; the echo c


# ============================================
# PART 9: THE DRY RUN
# ============================================

find . -name '*.log' -print0 | xargs -0 -t echo
# the echo ./a.log ./b.log


# ============================================
# PART 10: THE LFCS PIPELINE
# ============================================

# Remove the old log files
find /var/log -name '*.log' -mtime +30 -print0 | xargs -0 rm

# The parallel compression
find /var/log -name '*.log' -print0 | xargs -0 -P 4 -n 1 gzip

# The bulk rename
find . -name '*.txt' -print0 | xargs -0 -I {} mv {} {}.bak

# The safe delete with the confirmation
find . -name '*.tmp' -print0 | xargs -0 -r -p rm

# The bulk chmod
find . -name '*.sh' -print0 | xargs -0 chmod +x

# The count the lines in the many files
find . -name '*.log' -print0 | xargs -0 wc -l

# The bulk copy
find . -name '*.conf' -print0 | xargs -0 -I {} cp {} /backup/

# The search in the many files
find . -name '*.log' -print0 | xargs -0 grep 'ERROR'

The ten parts show the basic xargs, the null separator, the placeholder, the parallel, the verbose, the empty input guard, the custom delimiter, the lines per command, the dry run, and the LFCS pipeline.


Quick Reference

The xargs Options

The optionThe purpose
-0The null-separated
-n NThe N arguments per command
-I {}The placeholder
-P NThe N parallel
-tThe print the command
-pThe prompt
-rThe no-run-if-empty
-d XThe delimiter
-L NThe N lines per command
-a fileThe read from the file
-E XThe end-of-file string

The Safe Pair

The commandThe option
find-print0
xargs-0
xargs-r (the GNU)

The Common Patterns

The patternThe command
The deletefind ... -print0 | xargs -0 rm
The parallelfind ... -print0 | xargs -0 -P 4 -n 1 cmd
The placeholderfind ... | xargs -I {} cmd {}
The grepfind ... -print0 | xargs -0 grep 'x'
The countfind ... -print0 | xargs -0 wc -l

The Default Behavior

The aspectThe default
The commandecho
The delimiterThe whitespace
The argumentsThe as many as possible
The parallelThe 1 (the sequential)
The empty inputThe run

The Exit Status

The statusThe meaning
0The success
123The any invocation exited 1-125
124The command exited 255
125The command killed by the signal
126The command cannot be run
127The command not found

Best Practices

โœ… Do This:

# Use the -print0 and the -0 for the file names
find . -name '*.log' -print0 | xargs -0 rm                                  # โœ…
# Use the -r for the empty input
find . -name '*.log' -print0 | xargs -0 -r rm                               # โœ…
# Use the -n for the batch
seq 1 100 | xargs -n 10 echo                                                # โœ…
# Use the -I for the placeholder
find . -name '*.txt' | xargs -I {} cp {} /backup/                           # โœ…
# Use the -P for the parallel
find . -name '*.jpg' -print0 | xargs -0 -P 4 -n 1 convert                   # โœ…
# Use the -t for the dry run
find . -name '*.log' -print0 | xargs -0 -t echo                             # โœ…

โŒ Don’t Do This:

# Don't use the xargs without the -0 for the spaces
find . -name '*.log' | xargs rm  # the space split                          // โŒ
# Don't use the -0 without the -print0
echo 'file1 file2' | xargs -0 rm  # the single item                        // โŒ
# Don't run the rm on the empty input
echo '' | xargs rm  # the no args                                           // โŒ
# Don't mix the -I and the -n
find . | xargs -I {} -n 2 rm {}  # the -I overrides the -n                  // โŒ
# Don't use the sh -c with the untrusted input
echo 'x; rm -rf /' | xargs sh -c  # the injection                           // โŒ
# Don't use the parallel with the interleaved output
find . | xargs -P 4 grep 'x'  # the mixed output                            // โŒ
# Don't forget the -r in the scripts
find . -name '*.log' | xargs rm  # the run on the empty                     // โœ… (the -r is the safety)

Common Pitfalls

The pitfallThe whyThe fix
The space splitThe default whitespaceUse the -0 with the -print0
The empty input runsThe no -rAdd the -r
The -0 with the newlineThe wrong delimiterUse the -print0
The -I and the -n conflictThe -I implies -L 1Use the one
The parallel output interleavedThe -PUse the separate files
The command injectionThe untrusted inputValidate or avoid the sh -c
The ARG_MAX exceededThe long listUse the -n

Real-World Examples

1. The Safe Delete

find /var/log -name '*.log' -mtime +30 -print0 | xargs -0 rm

2. The Parallel Compression

find . -name '*.log' -print0 | xargs -0 -P 4 -n 1 gzip

3. The Bulk Rename

find . -name '*.txt' -print0 | xargs -0 -I {} mv {} {}.bak

4. The Bulk Chmod

find . -name '*.sh' -print0 | xargs -0 chmod +x

5. The Search in the Many Files

find . -name '*.log' -print0 | xargs -0 grep 'ERROR'

6. The Count the Lines

find . -name '*.log' -print0 | xargs -0 wc -l

7. The Bulk Copy

find . -name '*.conf' -print0 | xargs -0 -I {} cp {} /backup/

8. The Dry Run

find . -name '*.log' -print0 | xargs -0 -t echo

9. The Prompt

find . -name '*.tmp' -print0 | xargs -0 -p rm

10. The Complete

find . -name '*.log' -print0 | xargs -0 -r -P 4 -n 1 gzip

Visual

The xargs Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE xargs FLOW                                              โ”‚
โ”‚                                                              โ”‚
โ”‚  find . -name '*.log' -print0 | xargs -0 rm                  โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚find          โ”‚    โ”‚xargs         โ”‚    โ”‚rm            โ”‚    โ”‚
โ”‚  โ”‚              โ”‚    โ”‚              โ”‚    โ”‚              โ”‚    โ”‚
โ”‚  โ”‚ the paths โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ–บโ”‚ the items โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ–บโ”‚ the args     โ”‚    โ”‚
โ”‚  โ”‚ (the null-   โ”‚    โ”‚ (the null-   โ”‚    โ”‚              โ”‚    โ”‚
โ”‚  โ”‚  separated)  โ”‚    โ”‚  separated)  โ”‚    โ”‚              โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ”‚  The xargs converts the stdin items to the command args.     โ”‚
โ”‚  The -0 handles the null-separated input.                    โ”‚
โ”‚  The rm runs once with the many args (or the batches).       โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Safe Pair

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE SAFE PAIR                                               โ”‚
โ”‚                                                              โ”‚
โ”‚  โŒ THE UNSAFE:                                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  find . -name '*.log' | xargs rm                     โ”‚    โ”‚
โ”‚  โ”‚                                                       โ”‚    โ”‚
โ”‚  โ”‚  The "my file.log" โ†’ the "my" and the "file.log"     โ”‚    โ”‚
โ”‚  โ”‚  The wrong files are removed.                        โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ”‚  โœ… THE SAFE:                                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  find . -name '*.log' -print0 | xargs -0 rm          โ”‚    โ”‚
โ”‚  โ”‚                                                       โ”‚    โ”‚
โ”‚  โ”‚  The "my file.log" โ†’ the "my file.log" (the one item)โ”‚    โ”‚
โ”‚  โ”‚  The correct files are removed.                      โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Placeholder

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE PLACEHOLDER                                             โ”‚
โ”‚                                                              โ”‚
โ”‚  find . -name '*.txt' | xargs -I {} mv {} {}.bak             โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  The item: file1.txt                                 โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the mv file1.txt file1.txt.bak                  โ”‚    โ”‚
โ”‚  โ”‚                                                       โ”‚    โ”‚
โ”‚  โ”‚  The item: file2.txt                                 โ”‚    โ”‚
โ”‚  โ”‚    โ†’ the mv file2.txt file2.txt.bak                  โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ”‚  The -I {} replaces the {} with the item.                    โ”‚
โ”‚  The -I implies the -L 1 (the one item per command).         โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Parallel

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE PARALLEL                                                โ”‚
โ”‚                                                              โ”‚
โ”‚  find . -name '*.jpg' -print0 | xargs -0 -P 4 -n 1 convert   โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  the item 1 โ”€โ”€โ–บ convert (the process 1)              โ”‚    โ”‚
โ”‚  โ”‚  the item 2 โ”€โ”€โ–บ convert (the process 2)              โ”‚    โ”‚
โ”‚  โ”‚  the item 3 โ”€โ”€โ–บ convert (the process 3)              โ”‚    โ”‚
โ”‚  โ”‚  the item 4 โ”€โ”€โ–บ convert (the process 4)              โ”‚    โ”‚
โ”‚  โ”‚                                                       โ”‚    โ”‚
โ”‚  โ”‚  The 4 at once. The wall-clock is the reduced.       โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                              โ”‚
โ”‚  The -P 4 sets the 4 parallel. The -n 1 runs the 1 per       โ”‚
โ”‚  command.                                                     โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
xargsThe stdin to the arguments
-0The null-separated
-n NThe N arguments per command
-I {}The placeholder
-P NThe N parallel
-tThe print the command
-rThe no-run-if-empty
-d XThe delimiter
-L NThe N lines per command
The defaultThe echo, the whitespace
The safe pairThe find -print0 + the xargs -0

Key takeaways:

  • The xargs reads the items from the standard input and runs the command with the items as the arguments. The echo 'file1 file2' | xargs rm converts the pipe to the rm file1 file2 command.
  • The -0 is the critical for the safe. The find -print0 and the xargs -0 use the null separator, and the file names with the spaces are the preserved.
  • The -n limits the arguments per command. The -n 1 runs the command once per item, and the -n 10 runs it with the ten items.
  • The -I {} replaces the placeholder. The xargs -I {} mv {} {}.bak runs the command once per item with the {} replaced.
  • The -P runs the commands in the parallel. The -P 4 runs the four commands at once, and the -n 1 runs the one item per command.
  • The -r does not run the command on the empty input. The -r is the GNU extension, and it is the safety for the scripts.
  • The xargs respects the ARG_MAX. The command line has the length limit, and the xargs splits the long lists into the batches.
  • The result is the argument-list building. The pipe feeds the items, and the xargs builds the arguments. The result is the bridge between the filters and the utilities, which is the foundation of the shell pipelines.

Remember: The xargs reads the items from the standard input and runs the command with the items as the arguments. The -0 handles the null-separated input, and the find -print0 produces it. The -n limits the arguments, the -I {} replaces the placeholder, the -P runs in the parallel, and the -r guards the empty input. The result is the argument-list building, which is the foundation of the shell pipelines.



Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!