外壳程序(例如bash)如何扩展通配符模式?


9

假设一个目录有100个文件,以字母“ a”开头。

如果我grep <some string> a*从终端执行a ,外壳将如何处理呢?

它将扩展正则表达式,按顺序获取每个文件中以a和grep开头的所有文件的列表吗?还是有其他方法?

假设我有一个以“ a”开头的上述文件名数组。如果我编写一个for循环并在shell脚本或ac程序中自己进行迭代,会花费更多/更少的时间吗?


7
顺便说一句,这glob不是一个正则表达式。很大的区别。
亚伦·马拉斯科

Answers:


8

首先,一个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已经“足够快”。


感谢您提供非常详细的答案。实际上,我需要grep压缩文件(每个文件只有几GB)。我有这些文件的列表。现在,我可以选择构建一个正则表达式(复杂)以匹配那些文件,或者遍历已知列表并在其中每个文件上运行grep(简单)。因此担心性能。
harithski

尝试zcatzgrep; 无需一一解压
jw013 2011年

当然是。我正在使用zgrep。
harithski

6

是的,它将扩展为文件列表,并将结果列表提供给grep程序。至少man bash在“ 路径名扩展”小节中是这样说的。

在您提到的简单情况下,还有另一种使用扩展的方法:编写grep <some_string> a然后按*,然后按ESC。这将在命令行中直接扩展匹配文件的列表,因此您可以在按之前确认列表是否正确Enter

至于问题的第二部分,要看情况。如果您打算编写一个在每个文件上依次运行grep的for循环,那肯定会比较慢,因为grep程序将不会运行一次,而是每个文件运行一次。然而,什么重要的是要记住的是,是有一定限度的,你可以使用命令行参数的展开长度,但它通常是相当高的。要查看,可以尝试grep adasdsadf /usr/*/*/* >/dev/null


2
ESC+*与让bash扩展*并不完全相同,因为ESC+*它将插入点文件(以a开头的名称.),而的扩展*取决于dotglob shopt设置。C-x *默认情况下,扩展和插入glob的键序列是映射到readline命令的键序列glob-expand-word
2011年

1
@ jw013感谢您提供信息!它似乎并没有改变a*扩展的情况,但是在更广泛的范围内当然很重要。
rozcietrzewiacz 2011年

2
zsh注意:只需按一下可扩展参数(全局模式,大括号扩展,命令替换等)的Tab键,即可对其进行扩展。
斯蒂芬·吉梅内斯

@ jw013实际上,我只是测试了此C-x快捷方式,它没有扩展系统上的文件列表(使用bash)。
rozcietrzewiacz 2011年

1
@roz对-我几乎从未使用过它,只是想指出(而不是挑剔的)区别:)。 C-x *glob只做仅处理文件名的glob,但Esc *实际上它做的更多insert-completions,因为在所有可能的补全中它都是。例如,这意味着Esc *在空命令行上使用将在您的中插入每个可执行文件的名称$PATH
2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.