Linux xargs Command
xargs (Extended ARGuments) is a filter that passes parameters to commands and a tool that combines multiple commands.
xargs can convert piped or standard input (stdin) data into command-line arguments and can also read data from file outputs.
xargs can convert single-line or multi-line text input into other formats, such as multi-line to single-line, and single-line to multi-line.
The default command for xargs is echo, which means that the input passed through the pipe to xargs will include newlines and spaces, but xargs will replace newlines and spaces with spaces.
xargs is a powerful command that can capture the output of one command and pass it to another command.
The reason to use this command is that many commands do not support piping parameters through a pipe, but there is a need for this in daily work, so the xargs command is used. For example:
find /sbin -perm +700 |ls -l # This command is incorrect
find /sbin -perm +700 |xargs ls -l # This is the correct way
xargs is typically used with pipes.
Command Format:
somecommand |xargs -item command
Parameters:
- -a file Read input from a file as stdin
- -e flag Note that sometimes it might be -E. The flag must be a space-separated marker. xargs will stop when it encounters this flag.
- -p Prompt the user before executing each argument.
- -n num Specify the number of arguments to use at a time. The default is to use all arguments.
- -t Print the command before executing it.
- -i or -I (depending on Linux support) Assign each item name from xargs, typically line by line, to {}, which can be used as a placeholder.
- -r no-run-if-empty Stop xargs if the input is empty.
- -s num Maximum number of characters for the command line, referring to the maximum command line length for the command following xargs.
- -L num Read num lines from standard input and pass them to the command.
- -l Same as -L.
- -d delim Delimiter. The default delimiter for xargs is a newline, and the default delimiter for arguments is a space. This option modifies the xargs delimiter.
- -x Exit, mainly used in conjunction with -s.
- -P Modify the maximum number of processes. The default is 1, and 0 means as many as possible. I couldn't think of an example for this; it probably isn't used often.
Examples
xargs as a replacement tool, reading input data and reformatting it for output.
Define a test file with multiple lines of text data:
# cat test.txt
a b c d e f g
h i j k l m n
o p q
r s t
u v w x y z
Convert multi-line input to single-line output:
# cat test.txt | xargs
a b c d e f g h i j k l m n o p q r s t u v w x y z
Use the -n option for multi-line output:
# cat test.txt | xargs -n3
a b c
d e f
g h i
j k l
m n o
p q r
s t u
v w x
y z
Use the -d option to define a custom delimiter:
# echo "nameXnameXnameXname" | xargs -dX
name name name name
Combine with the -n option:
# echo "nameXnameXnameXname" | xargs -dX -n2
name name
name name
Read stdin and pass the formatted parameters to a command.
Assume a command sk.sh and a file containing parameters arg.txt:
#!/bin/bash
# sk.sh command content, print all parameters.
echo $*
arg.txt file content:
# cat arg.txt
aaa
bbb
ccc
The -I option for xargs specifies a placeholder string {}, which is replaced during xargs expansion. When used with xargs, each parameter command is executed once:
# cat arg.txt | xargs -I {} ./sk.sh -p {} -l
-p aaa -l
-p bbb -l
-p ccc -l
Copy all image files to the /data/images directory:
ls *.jpg | xargs -n1 -I {} cp {} /data/images
xargs combined with find:
find . -name "*.txt" | xargs rm
When deleting too many files with rm
, you might encounter an error message: /bin/rm Argument list too long. Use xargs
to avoid this issue:
find . -type f -name "*.log" -print0 | xargs -0 rm -f
xargs -0
uses \0
as the delimiter.
Count the number of lines in all PHP files in a source code directory:
find . -type f -name "*.php" -print0 | xargs -0 wc -l
Find all JPG files and compress them:
find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz
Other applications of xargs
If you have a file containing many URLs you want to download, you can use xargs
to download all the links:
# cat url-list.txt | xargs wget -c