A quick question. A command
cat * | wc -c
doesn’t require xargs, but the command
ls | xargs echo
requires xargs command. Can please someone explain me the concept of xargs more clearly. Thanks.
Advertisement
Answer
In short, xargs
converts stdin
(standard input) to arguments for the command you specify. For example
$ seq 1 3 1 2 3 $ seq 1 3 | xargs echo 1 2 3
seq
, as you can see, prints a sequence to stdout
. We pipe (|
) that output to xargs
on stdin
. xargs
calls echo
with stdin
as arguments, so we get echo 1 2 3
.
As el.pescado said, wc
accepts input on stdin
(you can also give it a file argument). Because cat
prints a file to stdout
, you can pipe it directly to wc
.
$ cat text This is only a test $ cat text | wc 2 5 20 $ wc text 2 5 20 text
echo
does not accept anything from stdin
. That would be weird, since echo
‘s job is to print to stdout
– you could already print anything you’d pipe it. So, you use xargs
to convert the stream to arguments.
echo
might be too trivial a command to see what’s going on, so here’s a more real-world example. Say we’ve got a directory with some files in it:
$ ls bar1 foo1 foo2 foo3 foo4 foo5 foo6
We’ve had it up to here with foo
, and we want to delete all of them, but we can’t be bothered to type rm foo1 foo2 ...
. After all, we’re programmers, and we’re lazy. What we can do is…
$ ls foo* | xargs rm $ ls bar1
rm
expects arguments, ls foo*
prints every file we want to remove, and xargs
does the translation.
As a side note, sometimes you want to split up stdin
into smaller pieces. xargs -n
is highly useful for that, and passes N arguments at a time to your final command.
$ ls foo* | xargs -n2 echo foo1 foo2 foo3 foo4 foo5 foo6