Handle Too-Long Command Lines with xargs
xargs
is one of those UNIX utilities that seems pretty useless when you first hear about it -- but turns into one of the handiest tools you can have.
xargs
reads a group of arguments from its standard input, then runs a UNIX command with that group of arguments. It keeps reading arguments and running the command until it runs out of arguments. The shell's backquotes do the same kind of thing, but they give all the arguments to the command at once. This can give you aToo many arguments
error.
Here are a couple of examples:
If you want to print most of the files in a large directory, put the output of
ls
into a file. Edit the file to leave just the filenames you want printed. Give the file toxargs
' standard input:% ls > allfiles.tmp % vi allfiles.tmp % xargs lpr <>
What did that do? With lines like these in
allfiles.tmp
:% cat allfiles.tmp afile application ... yoyotest zapme
xargs
ran one or morelpr
commands, each with a group of arguments, until it had read every word in the file:lpr afile application ... ... lpr ... yoyotest zapme
The standard output of
xargs
is the standard output of the commands it runs. So, if you'd createdallfiles.tmp
above but you wanted to format the files withpr
first, you could type:% xargs pr <>
Then
xargs
would run all of thesepr
commands. The shell would pipe their standard outputs to a singlelpr
command. Actually, the shell is piping the standard output ofxargs
. As I said above,xargs
sends the standard output of commands it runs to its own standard output:pr afile application ... ... pr ... yoyotest zapme
In this next example,
find
gets a list of all files in the directory tree. Next, we usexargs
to read those filenames and rungrep - l
to find which files contain the word "WARNING". Next, we pipe that to a setup withpr
andlpr
, like the one in the previous example:% find . -type f -print | xargs grep -l WARNING | xargs pr | lpr
"Huh?" you might say. Just take that step by step. The output of
find
is a list of filenames, like ./afile ./bfile ... ./adir/zfileand so on. The firstxargs
gives those filenames to one or moregrep - l
commands:grep -l WARNING ./afile ./bfile ... ... grep -l WARNING ./adir/zfile ...
The standard output of all those
grep
s is a (shortened) list of filenames that match. That's piped to anotherxargs
- it runspr
commands with the filenames thatgrep
found.UNIX is weird and wonderful!
Sometimes you don't want
xargs
to run its command with as many arguments as it can fit on the command line. The- n
option sets the maximum number of argumentsxargs
will give to each command. Another handy option,- p
, prompts you before running each command.Here's a directory full of files with errors (whose names end with
.bad
) and corrected versions (named.fixed
). I usels
to give the list of files toxargs
; it reads two filenames at once, then asks whether I want to rundiff - c
to compare those two files. It keeps prompting me and runningdiff - c
until it runs out of file pairs:% ls chap1.bad chap1.fixed chap2.bad chap2.fixed ... chap9.bad chap9.fixed % ls | xargs -p -n2 diff -c diff -c chap1.bad chap1.fixed ?...y ...... diff -c chap2.bad chap2.fixed ?...n diff -c chap3.bad chap3.fixed ?...y ...... ...
As tomorrow's article explains, xargs
can have trouble if an argument has white space inside a word. Luckily, the GNU xargs
solves the problem.
Source : http://linuxdevcenter.com/pub/a/linux/lpt/09_21.html
Comments
Post a Comment