当从 ls | 通过管道传输结果时,head 不起作用grep

head doesn't work when piped a result from ls | grep

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

ls -p | grep -v /

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

ls -p | grep -v / | head

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

有人能帮忙吗?

查找当前目录下所有不属于目录的文件:

find . -mindepth 1 -maxdepth 1 -type f

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

你的错误是假设命令从标准输入接收的是参数。不是。

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

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

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

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

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

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

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

你可以通过这样的方式实现你想要的:

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

这会找到每个文件,然后打印 header/separator 行,以及每个文件的第一行。