xargs

From Wikipedia, the free encyclopedia

Jump to: navigation, search

xargs is a command on Unix and most Unix-like operating systems. It is useful when one wants to pass a large number of arguments to a command. Until Linux kernel 2.6.23, arbitrarily long lists of parameters could not be passed to a command [1], so xargs will break the list of arguments into sublists small enough to be acceptable.

For example, commands like:

rm /path/*
rm `find /path -type f` 

will fail with an error message of "Argument list too long" if there are too many files in /path. However this version (functionally equivalent to rm `find /path -type f`) will not fail:

find /path -type f -print0 | xargs -0 rm

In this example, find feeds the input of xargs with a long list of file names. xargs then splits this list into sublists and calls rm once for every sublist. This is more efficient than this functionally equivalent version:

find /path -type f -exec rm '{}' \;

which calls rm once for every single file. Note however that with modern versions of find, the following variant does the same thing as the xargs version:

find /path -type f -exec rm '{}' +

xargs often covers the same functionality as the backquote feature of many shells, but is more flexible and often also safer, especially if there are blanks or special characters in the input. It is a perfect companion for commands that output long lists of files like find, locate and grep.

Contents

[edit] Examples

find . -name "*.foo" | xargs grep bar

The above is equivalent to:

grep bar `find . -name "*.foo"`

Note that the above command uses backticks (`), not single quotes ('). It searches in all files in the current directory and its subdirectories which end in .foo for occurrences of the string bar. These commands will not work as expected if there are whitespace characters, including newlines, in the filenames. In order to avoid this limitation one may use:

find . -name "*.foo" -print0 | xargs -0 grep bar

The above command uses GNU specific extensions to find and xargs to separate filenames using the null character;


find . -name "*.foo" -print0 | xargs -0 -t -r vi

The above command is similar to the former one, but launches the vi editor for each of the files. The -t prints the command to stderr before issuing it. The -r is a GNU extension that tells xargs not to run the command if no input was received.


find . -name "*.foo" -print0 | xargs -0 -I mv {} /tmp/trash

The above command uses -I to tell xargs to replace {} with the argument list. Note that not all versions of xargs supports the {} syntax. In those cases you may specify a string after -I that will be replaced, e.g.


find . -name "*.foo" -print0 | xargs -0 -I xxx mv xxx /tmp/trash

The above command uses string xxx instead of {} as the argument list marker.


find . -maxdepth 1 -type f -name "*.mp3" -print0 | xargs -0 -r cp -v -p --target-directory=/home/media

The command above does the same as:

cp -v -p *.mp3 /home/media

however, the former command which uses find/xargs/cp is more resource efficient and will not halt with an error if the number of files is too large for the cp command to handle. Other way (choosing where to put your arguments) to do it is:

find . -maxdepth 1 -type f -name "*.mp3" -print0 | xargs -0 -IMYFILES cp MYFILES /home/media

The -I in the above command tells xargs what replacement string you want to use (otherwise it adds the arguments to the end of the command). You can also use -L to limit the number of arguments. If you do that, the command will be run repeatedly until it’s out of arguments. Thus, -L1 runs the command once for each argument (needed for tools like tar and such).

[edit] References

[edit] External links

[edit] Manual pages

Personal tools