Answers:
首先,一个nitpick:类似于a*
普通shell语法的字符串是一个glob,其作用与正则表达式不同。
总体而言,shell解释器(即bash)将字符串扩展为a*
与pattern匹配的每个文件名的列表a*
。然后,它们成为单个实例的命令行参数的一部分grep
(对于程序员,所有扩展的单词都作为单独的字符串放入的argv
参数中main
)。grep
然后,该单个命令将以其选择的任何方式解析参数,这取决于将grep
这些参数解释为文件名,选项,选项参数,正则表达式等,并采取适当的措施。一切顺序发生(AFAIK没有grep
实现使用多个线程)。
如果您在Shell脚本中实现循环以执行相同的操作,则由于以下原因,几乎可以肯定它比上述过程要慢。如果为每个文件生成一个新的grep进程,由于不必要地增加了创建进程的开销,这肯定会变慢。如果您是在shell脚本中自己构造参数列表并使用的单个实例grep
,则在shell中执行的任何操作仍然会变慢,因为必须解释shell命令(通过bash),这会增加一层代码,您将只是在编译的代码中重新实现bash在内部已经更快地完成的工作。
至于用C编写自己的代码,您可能可以轻松获得与第一段中描述的过程相当的性能,但是不太可能在当前grep / bash实现上获得足够的性能提升,以证明时间合理无需研究特定于机器的性能优化或牺牲便携性。也许您可以尝试提出的任意可并行化版本grep
,但即使那样也可能无济于事,因为您更可能受I / O约束而不是CPU约束。对于大多数“正常”目的,glob扩展和grep已经“足够快”。
zcat
和zgrep
; 无需一一解压
是的,它将扩展为文件列表,并将结果列表提供给grep
程序。至少man bash
在“ 路径名扩展”小节中是这样说的。
在您提到的简单情况下,还有另一种使用扩展的方法:编写grep <some_string> a
,然后按*
,然后按ESC。这将在命令行中直接扩展匹配文件的列表,因此您可以在按之前确认列表是否正确Enter。
至于问题的第二部分,要看情况。如果您打算编写一个在每个文件上依次运行grep的for循环,那肯定会比较慢,因为grep程序将不会运行一次,而是每个文件运行一次。然而,什么是重要的是要记住的是,是有一定限度的,你可以使用命令行参数的展开长度,但它通常是相当高的。要查看,可以尝试grep adasdsadf /usr/*/*/* >/dev/null
。
ESC+*
与让bash扩展*并不完全相同,因为ESC+*
它将插入点文件(以a开头的名称.
),而的扩展*
取决于dotglob
shopt
设置。C-x *
默认情况下,扩展和插入glob的键序列是映射到readline命令的键序列glob-expand-word
。
a*
扩展的情况,但是在更广泛的范围内当然很重要。
zsh
注意:只需按一下可扩展参数(全局模式,大括号扩展,命令替换等)的Tab键,即可对其进行扩展。
C-x
快捷方式,它没有扩展系统上的文件列表(使用bash)。
C-x *
glob只做仅处理文件名的glob,但Esc *
实际上它做的更多insert-completions
,因为在所有可能的补全中它都是。例如,这意味着Esc *
在空命令行上使用将在您的中插入每个可执行文件的名称$PATH
。
glob
不是一个正则表达式。很大的区别。