对不起,如果这是一个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")