一尘不染

Linux为什么我无法通过管道找到结果到rm?

linux

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

要找到然后删除我可以使用的东西

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

但是为什么我不能像这样将结果通过管道传递给rm

find . -name ".txt" | rm

就像我将其输送到grep

find . -name ".txt" | grep a

我从某处读到rm不会从stdin接收输入,因此我无法通过管道传输它,但这是什么意思?当我输入rm
a.txt时,它会从标准输入中读取,就像我可以grep一样吗?还是stdin和命令行之间有区别。帮帮我!


阅读 419

收藏
2020-06-03

共1个答案

一尘不染

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

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

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用于将所有换行符转换为空字符。

2020-06-03