用于排除二进制文件的zsh glob限定符

用于排除二进制文件的zsh glob限定符,zsh,glob,Zsh,Glob,我正在查找当前目录和所有子目录中包含字符串“abc”的文件: grep abc **/*(.) 输出包含以下行: ... Binary file test.pdf matches ... 是否可以在glob限定符中排除二进制文件 EDIT:这里使用grep只是一个例子。我感兴趣的是通过zsh globbing限定符排除二进制文件,而不是相应的grep选项。消息“binary file test.pdf matches”不是由zsh打印的,而是由grep本身打印的 原因是,在大多数情况下,如果

我正在查找当前目录和所有子目录中包含字符串“abc”的文件:

grep abc **/*(.)
输出包含以下行:

...
Binary file test.pdf matches
...
是否可以在glob限定符中排除二进制文件

EDIT:这里使用
grep
只是一个例子。我感兴趣的是通过zsh globbing限定符排除二进制文件,而不是相应的grep选项。

消息“binary file test.pdf matches”不是由zsh打印的,而是由grep本身打印的

原因是,在大多数情况下,如果要打印包含模式的二进制文件的行,它也会打印“垃圾”(即不可打印的字符、非常长的行等)

在您的示例中,**/*(.)是一个zsh扩展。 您可以使用echo检查它扩展到什么:

$ echo **/*(.)
请注意**/*(.)与顶部目录中用点表示的文件不匹配

$ mkdir test
$ cd test
$ touch .mytest
$ echo  **/*(.)
zsh: no matches found: **/*(.)
现在,如果要在当前目录中递归查找包含特定模式的文件,有一种非常简单的方法:

$ grep -rI .
如果要忽略当前目录中以点开头的文件:

$ grep -r *
关于使用zsh globbing过滤二进制文件。 这是zshexpn(1)的一部分:

请注意,尽管手册上说的是“纯文本文件”,但它并不意味着“纯文本文件”。 它意味着常规文件

恕我直言,如果文件的内容是二进制还是非二进制,zsh没有基于glob文件的选项

Zsh在全局绑定时不读取文件的内容,而是使用可用的文件系统元数据

因此,如果zsh实现此功能,全局绑定时间将比当前可用的全局绑定时间慢得多(当然,除非文件系统实现“标记”二进制文件的方法,这在IMO中是不可能的)

您可以尝试用execution标志过滤掉文件,但这将是非常不精确的(即,可执行脚本将被过滤掉,而非可执行二进制文件将被过滤掉)


这个任务更适合grep本身,因为他无论如何都会读取文件。

您可以作为glob限定符执行任意代码。在
zshexpn(1)
中查找
estring
+cmd

没有任何设置:

ls **/*(.e:'file --mime $REPLY | grep -iqv binary':)
或者让它不那么尴尬:

notbinary() { file --mime $REPLY | grep -iqv binary }
ls **/*(.+notbinary)

定义“二进制文件”
grep
可以识别它们,因为它实际上查看每个文件的内容;它不是某些(大多数?)文件系统跟踪的属性,而且
zsh
在查找模式匹配时只查看文件系统元数据。谢谢。我指的是包含二进制数据的文件,如pdf,但不同于纯文本文件。好的,仔细想想,所有文件都以某种方式包含二进制数据。似乎zsh globbing无法实现我想要做的事情。如果你把你的评论作为回答,我会接受的。更新:
grep-imc**/*(.)
做我想做的事;“文本”文件只是一个文件,其字节被解释为文本的ASCII(或UTF-8或其他)编码
grep
只是根据高位设置的字节比例进行猜测。一个包含大量非ASCII字母的UTF-8文件同样会被解释为二进制文件。我不得不编辑我的问题。我用grep作为例子;我想通过zsh globbing而不是grep选项来实现二进制文件的排除。这样,我就可以在grep以外的命令中重用“exclude binary”模式@上面的切普纳很好地解释了为什么这不可能。如果你能在回答中提到这一点,我可以接受。我现在明白你的意思了。我不认为zsh天生就有这个特性。你必须写一个脚本。
notbinary() { file --mime $REPLY | grep -iqv binary }
ls **/*(.+notbinary)