认为
[root@iz2ze9wve43n2nyuvmsfx5z /]# find . -maxdepth 2 -type d | ls
bin dev home lib64 media opt root sbin sys usr
boot etc lib lost+found mnt proc run srv tmp var
ls 什么也没做,作为救援我应该将它们重建为 ls 的列表
find . -type d | xargs ls
#millions of outputs
但是,grep 做得很好
[root@iz2ze9wve43n2nyuvmsfx5z /]# find . -maxdepth 2 -type d | grep home
./home
我怎么能区分一个命令不是作为第二个发射器诞生的,与不了解而不是尝试、错误测试和记住。
您要么学习并记住各种程序的作用,要么查看手册页。
的描述
ls
是:其中 FILEs 指的是概要:
要记住的重要部分
ls
是它将生成有关您在命令行上提供的“文件”的信息。该手册未描述ls
读取任何输入(例如来自管道)的任何方式。对比
ls
手册页,说cat
手册页,它说:有了
cat
,你可以cat /some/file
或者你可以echo hi | cat
。因此,在您的第一个示例中,
find
去做了一些工作,并在其标准输出上传递了一些(或没有)目录名称,这变成了ls
标准输入,它ls
立即被忽略了。由于您ls
没有列出要列出的文件,因此它默认列出当前目录。在你的第二个例子中,
find
去做(更多)工作,生成它在其标准输出上找到的每个目录,然后将其xargs
作为标准输入呈现。xargs
读取的手册页,部分:so then
ls
根据需要多次调用,给定 stdin 上的输入行数。同样的想法转化为你的第三个命令:
find
将任何目录名称传递给grep
的标准输入;grep 的手册页再次部分说明:管道的概念很简单,但却很强大,您只需要知道程序产生什么样的输出以及程序是否可以使用其标准输入上的输入。
grep
是在这些情况下最常用的工具之一。您可以将它用作主要命令:在这种情况下
grep
知道文件的名称,或者您可以在其标准输入上向其发送输入:... 在这种情况下,grep 现在不再知道任何文件名(
cat
知道它们,然后将它们的内容生成到标准输出),因此现在 grep 无法知道哪些文件包含文本——只有哪些行匹配。将一堆命令链接在一起变得很诱人——通常被半开玩笑地称为“单行”,因为“单行”可以变得足够长,可以在终端窗口中将两个第二行换成一个“管道”。同样,您必须确切地知道程序是如何产生和消耗输入的。
给定名为
file1
、file2
和的文件file3
,您可以执行以下操作:find
当将三个文件名生成为标准输出时,您不会感到惊讶——... xargs 编译列表并将其发送到
cat
--...谁看到这三个文件名并尽职尽责地将它们的内容转储到您的屏幕上。
当心,那么一个名为“这里的文件名”的文件;上面的
find
命令将输出:... xags 为它编制了一个列表
cat
--... 向其
cat
抱怨(向 stderr!):...后跟 file1、file2 和 file3 的内容。
您现在已准备好通过使用
find ... -exec
或 替代方法(例如find ... -print0 | xargs -0 ...
使用 NULL 作为文件名的分隔符)来避免这种情况。