Linux为什么我不能find结果rm?

对不起,如果这是一个noobie问题,但我找不到一个好的答案。

find然后删除我可以使用的东西

find . -name ".txt" -exec rm "{}" \; 

但是,为什么我不能把结果灌输给他们呢?

 find . -name ".txt" | rm 

就像我会pipe它grep

 find . -name ".txt" | grep a 

我从某个地方读过,rm不会从stdin那里得到input,所以我不能pipe它,但那是什么意思? 当我inputrm a.txt时,它会从标准input读取,就像我可以正确的grep? 或者stdin和命令行有区别。 帮帮我!

要扩展@Alex Gitelman的答案:是的,“标准输入”和命令行之间有区别。

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

与许多其他程序一样, rm从命令行接收参数,但忽略标准输入。 你可以用任何东西来管它, 它只会扔掉这些数据。 这就是xargs派上用场的地方。 它读取标准输入中的行,并将它们变成命令行参数,这样可以有效地将数据传送到另一个程序的命令行。 这是一个巧妙的把戏。

例如:

 find . -name ".txt" | xargs rm find . -name ".txt" | grep "foo" | xargs rm 

请注意,如果有任何包含换行符或空格的文件名,这将工作不正确。 要处理包含换行符或空格的文件名,您应该使用:

 find . -name ".txt" -print0 | xargs -0 rm 

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

 find . -name ".txt" | grep "foo" | tr "\n" "\0" | xargs -0 rm 

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

“为什么我不能找到结果?”

当您将某些东西传递给程序时,管道会替换键盘输入。 记住这一点,并问自己下一个问题:键盘会怎么做? 删除你的击键? (有点傻)接受交互控制? (除非有时需要确认,否则rm不是交互式的,确实可以由管道给出。)

事实上,当rm已经在运行,你不能输入命令让它删除文件….所以你不能用管道来做到这一点。

如果你记住一个管道取代了键盘/屏幕组合,事情将立即显得更合乎逻辑。

现在反过来。 您可以将数据流传输到grep 。 这是否意味着你可以让grep读取键盘上的按键作为输入数据呢?

是! 这实际上是它本身(没有管道)。

(顺便说一下,你不能管道,也不能输入搜索参数到grep

所以现在你知道为什么你不能把它当作命令行参数来工作。

tl; dr:

根据UNIX哲学解析一个程序:
文件输入,文件输出,键盘输入,屏幕输出。 – >管道只能取代键盘和屏幕。

管道将第一个命令的输出发送到第二个的标准输入。 rm不接受标准输入,所以你不能管道。 你可以使用xargs来达到同样的效果。 你可以在xargs 手册页中找到xargs的例子。

没有使用管道的替代方案:

 xargs rm -f <<< $(find . -name ".txt")