To expand on @Alex Gitelman's answer: yes, there's a difference between "standard input" and the command line.
When you type rm a.txt b.txt c.txt
, the files you list after rm
are known as arguments and are made available to rm through a special variable (called argv
internally). The standard input, on the other hand, looks to a Unix program like a file named stdin
. A program can read data from this "file" just as it would if it opened a regular file on disk and read from that.
rm
, like many other programs, takes its arguments from the command line but ignores standard input. You can pipe anything to it you like; it'll just throw that data away. That's where xargs
comes in handy. It reads lines on standard input and turns them into command-line arguments, so you can effectively pipe data to the command line of another program. It's a neat trick.
For example:
find . -name ".txt" | xargs rm
find . -name ".txt" | grep "foo" | xargs rm
Note that this will work incorrectly if there are any filenames containing newlines or spaces.
To deal with filenames containing newlines or spaces you should use instead:
find . -name ".txt" -print0 | xargs -0 rm
This will tell find
to terminate the results with a null character instead of a newline.
However, grep
won't work as before then. Instead use this:
find . -name ".txt" | grep "foo" | tr "
" "" | xargs -0 rm
This time tr
is used to convert all newlines into null characters.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…