且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Linux 为什么我不能通过管道找到结果到 rm?

更新时间:2023-11-14 12:49:10

扩展@Alex Gitelman 的回答:是的,标准输入"和命令行之间是有区别的.

To expand on @Alex Gitelman's answer: yes, there's a difference between "standard input" and the command line.

当您键入 rm a.txt b.txt c.txt 时,您在 rm 之后列出的文件称为 arguments,并且是通过一个特殊变量(内部称为 argv)提供给 rm.另一方面,标准输入看起来像一个名为 stdin 的文件的 Unix 程序.程序可以从这个文件"中读取数据,就像它在磁盘上打开一个常规文件并从中读取一样.

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 与许多其他程序一样,从命令行获取参数,但忽略标准输入.你可以通过管道传输任何你喜欢的东西;它只会丢弃这些数据.这就是 xargs 派上用场的地方.它读取标准输入上的行并将它们转换为命令行参数,因此您可以有效地将数据通过管道传输到另一个程序的命令行.这是一个巧妙的技巧.

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.

例如:

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

这将告诉 find 以空字符而不是换行符终止结果.但是,grep 不会像以前那样工作.而是使用这个:

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

这一次 tr 用于将所有换行符转换为空字符.

This time tr is used to convert all newlines into null characters.