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