我有一个文本文件foobar.txt,大约10KB,不是很长.然而,在高性能Linux机器上,以下匹配搜索命令大约需要10秒钟.
bash>shopt -s extglob
bash>[[ `cat foobar.txt` == ?(*[[:print:]])foobar ]]
Run Code Online (Sandbox Code Playgroud)
没有匹配:foobar.txt中的所有字符都是可打印的,但没有字符串"foobar".
搜索应该尝试匹配两个选项,每个选项都不匹配:
"foobar"
Run Code Online (Sandbox Code Playgroud)
这是不稳定的
*[[:print:]]foobar
Run Code Online (Sandbox Code Playgroud)
- 应该是这样的:
应该在一次通过中逐字符扫描文件,每次检查下一个字符是否都是
[[:print:]]foobar
Run Code Online (Sandbox Code Playgroud)
这应该也很快,每个角色都不应该花费毫秒.
事实上,如果我放弃?,就是这样做
bash>[[ `cat foobar.txt` == *[[:print:]]foobar ]]
Run Code Online (Sandbox Code Playgroud)
这是瞬间的.但这只是上面的第二种选择,没有第一种选择.
那么为什么这么久?
bash中的glob匹配器没有进行优化.例如,请参阅这个bug-bash线程,在此期间bash维护者Chet Ramey说:
它不是一个正则表达式引擎,它是一个即时解释的匹配器.
由于bash还包含一个正则表达式引擎(使用=~而不是==内部[[ ]]),因此可能没有太多动力去做任何事情.
在我的机器上,等效的regexp(^(.*[[:print:]])?foobar$)在很大程度上受到语言环境的影响[[:print:]]; 由于某种原因,这不会影响glob匹配器.设置LANG = C使正则表达式正常工作.
但是,对于大小的字符串,我会使用grep.