对不起,如果这是一个noobie问题,但我找不到一个好的答案.
要查找然后删除我可以使用的东西
find . -name ".txt" -exec rm "{}" \;
但为什么我不能把结果管道化为rm
find . -name ".txt" | rm
就像我会把它吹到grep一样
find . -name ".txt" | grep a
我从某个地方读过rm不接受来自stdin的输入,因此我无法管道但是这意味着什么?当我输入rm a.txt时,它会从标准输入中读取,就像我可以直接读取一样吗?或者stdin和命令行之间有区别.救命!
扩展@Alex Gitelman的答案:是的,"标准输入"和命令行之间存在差异.
键入时rm a.txt b.txt c.txt
,您列出的文件rm
称为参数,并通过特殊变量(argv
内部调用)提供给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
用于将所有换行符转换为空字符.
"为什么我不能把结果找到rm?"
当您将某些东西输送到程序时,管道将替换键盘输入.牢记这一点,并问自己下一个问题:如何rm
处理键盘?删除你的击键?(确实有点傻)接受互动控制?(rm
除非有时需要确认,否则不是交互式的,确实可以通过管道给出.)
事实上,当rm
它已经运行时,你不能输入命令让它删除文件....所以你不能用管道做到这一点.
如果你记住管道取代键盘/屏幕组合,事情会立即显得更合乎逻辑.
现在反过来了.您可以将数据流传输到grep
.这是否意味着您可以让grep读取键盘上的击键作为输入数据?
是!这实际上是它本身(没有管道)的作用.
(顺便提一下,你不能管道也不能输入搜索参数grep
)
所以现在你知道为什么你不能管道到rm 并期望它作为命令行参数.
tl;博士:
根据UNIX哲学解剖程序:
文件输入,文件输出,键盘输入,屏幕输出. - > Pipe只替换键盘和屏幕.