Xargs Command
Understanding the Xargs Command
The xargs command is a powerful utility in Unix-like operating systems that reads items from standard input, delimited by blanks (or a specified delimiter), and executes a command one or more times with any initial-arguments followed by items read from standard input. It's particularly useful for building and executing command lines from standard input, often in conjunction with other commands like find.
Common Xargs Use Cases and Examples
File Manipulation with Xargs
A frequent use case for xargs is to process a list of files generated by another command, such as find. For instance, to remove all files ending with .pdf:
# Find all file names ending with .pdf, then remove them.
find -name \*.pdf | xargs rm
While the above works, it's often more efficient and safer to use the built-in capabilities of find itself:
# The above, however, is better-written without xargs:
find -name \*.pdf -exec rm {} \+
# Although it's best to use find's own functionality, in this situation.
find -name \*.pdf -delete
Handling Filenames with Special Characters
When filenames might contain spaces or other special characters, xargs provides options to handle them safely. Using -print0 with find and -0 with xargs ensures that filenames are correctly interpreted, even if they contain newlines. The -r flag prevents xargs from running the command if the input is empty.
# Find all file names ending with '.pdf' and remove them. This approach also
# handles filenames with '\n' and skips '*.pdf' directories. The xargs(1) flag
# `-r` is equivalent to `--no-run-if-empty`, and the use of `-n` will in this
# case group execution by 10 files.
find -name \*.pdf -type f -print0 | xargs -0 -r -n 10 rm
Processing Files One by One
The -I option allows you to specify a placeholder for the input items, similar to how find -exec uses {}. This is useful when the command requires the input item to be placed at a specific position.
# If file names may contains spaces, you can use the xargs(1) flag `-I` and its
# proceeding argument to specify the filename placeholder, as in find(1)'s use
# of `{}` in `-exec`. Although find(1)'s `{}` needs not be cuddled by quotes, -
# xargs(1) does.
find -name \*.pdf | xargs -I {} rm -r '{}'
For simple cases like printing filenames, find's -printf option is often more efficient than using xargs.
# Print a list of files in the format of `*FILE=`. The use of xargs(1) flag
# `-n` here with its argument of `1` means to process the files one-by-one.
find -name \*.pdf | xargs -I {} -n 1 echo '&{}='
# The above is, however, much faster, more efficient, and easier without xargs.
find -name \*.pdf -printf '&%f=\n'
Grouping Arguments
xargs can group input items into batches to execute a command with multiple arguments at once. The -n option specifies the maximum number of arguments per command line.
# Group words by three in a string.
seq 1 10 | xargs -n 3
# Alternatively, and more efficiently, use Bash brace expansion, if available.
printf '%d ' {1..10} | xargs -n 3