当管道传输来自ls |的结果时,头部不起作用grep的

时间:2017-02-14 10:49:28

标签: linux bash grep ls

我正在尝试打印目录中所有文件的前10行。 目前,我正在使用:

ls -p | grep -v /

从ls的结果中删除所有目录,并仅返回目录中的文件。当我这样做的时候:

ls -p | grep -v / | head

我希望所有文件的前十行都会被打印出来,但它不起作用。

有人能帮忙吗?

2 个答案:

答案 0 :(得分:2)

要查找当前目录中不是目录的所有文件:

find . -mindepth 1 -maxdepth 1 -type f

然后,您可以使用-exec对每个文件运行命令。

答案 1 :(得分:2)

你的错误是假设命令从标准输入接收的是参数。事实并非如此。

当head从piped命令接收数据时,它接收的是数据流。 head命令正在以与从作为参数传递的一个文件读取的方式完全相同的方式读取该数据。可以这样想(这是伪代码,它不起作用):

PSEUDO_PIPELINE <= ls -p | grep -v /  # Not valid shell syntax
head PSEUDO_PIPELINE                  # Not valid shell syntax

实际上有一种(有效的)表达方式,它被称为进程替换:

head <(ls -p | grep -v /)

这将实现您观察到的完全相同(不需要的)结果,但更明显的是管道前面的命令实际上是文件,而不是参数列表。

标准输入(以及输出流标准输出和标准错误)是每个命令从其启动上下文接收的内容。这就像一个隐藏的论点&#34;如果你愿意,进程可以与它交互(通过读取它直到它到达文件的末尾,因为它是一个特殊的文件,但仍然是一个文件)。

现在你应该明白为什么你得到的是前面命令的前10行输出,而不是列出的每个文件的前10行。

你可以用这样的东西实现你想要的东西:

find . -mindepth 1 -maxdepth 1 -type f -exec printf "\n%s ------\n" {} \; -exec head {} \;

找到每个文件,然后打印标题/分隔符行,以及每个文件的第一行。