对大目录树使用ack / grep和globstar选项(性能问题?)

时间:2014-12-22 15:33:36

标签: performance bash grep ack file-search

我想使用bash的globstar选项“**”来搜索具有特定目录的文件,这与grep一样习惯。但是,以下命令刚刚启动并且什么也没做

ack PATTERN ~/projects/**/trunk/

如何使用类似的搜索位置搜索ack的文件?

编辑: 我尝试使用少量文件在模型目录上执行相同的行。它工作正常。因此,看起来运算符**需要太多资源(我猜它有递归),当我执行命令时,它只是遍历文件树。顺便说一句,以下命令会降低计算机速度,这是我尝试ack命令的原因。

grep -r PATTERN ~/projects/**/trunk/

所以,我想知道是否有一些解决方法可以实现我的目标(不一定是**)?

2 个答案:

答案 0 :(得分:2)

这应该有效:

\find -X . -type d -name trunk | xargs -L 1 ack PATTERN

来自-X手册

find参数
  

-X Permit find可以安全地与xargs(1)一起使用。如果文件名包含xargs(1)使用的任何分隔符,则会在标准错误上显示诊断消息,并且                文件被跳过。分隔字符包括单引号(' '') and double ("')引号,反斜杠(``\''),空格,制表符和换行符。

编辑:基于评论可能更好的解决方案(适用于BSD / GNU find / xargs AFAICT):

\find . -type d -name trunk -print0 | xargs -0 -L 1 ack PATTERN

我想这取决于你的结束命令是否可以使用有趣的文件名

来获取参数

答案 1 :(得分:1)

shell扩展** - 即如果您首先设置shopt -s globstar 并且 正在使用Bash 4.0或更高版本。在这种情况下,您可以查看shell与globstar匹配的确切文件。试试这些:

$ ls -d ~/projects/**/trunk/

或:

$ echo ~/projects/**/trunk/

然后,去喝一杯咖啡,因为globstar可能需要很长时间才能执行。您可能会发现,您甚至没有点击grepack返回匹配项的文件。你生命中的那段时间你已经浪费了,而且你永远不会回来。也可能看过Star Wars Holiday Special。至少你可以做一些喝酒游戏。

globstar的问题是shell被迫沿着整个目录树走,试图匹配**。然后,shell不会报告其结果,直到找到每个文件。它很慢,效率很低。

这是我系统上发生的事情:

$ time ls -d ~/projects/**/trunk
/Users/david/projects/foo/trunk           /Users/david/projects/barfoo/trunk
/Users/david/projects/bar/trunk           /Users/david/projects/foofoo/trunk
/Users/david/projects/foobar/trunk        /Users/david/projects/trunk

real    0m18.19s
user    0m0.52s
sys     0m15.83s

在那六个结果出现之前,我站在终点站盯着终端近20秒。如果我做~/**/trunk,则需要超过20分钟而不返回任何结果(我在20分钟后将其杀死)。

这里与find相当:

$ time find ~/projects -name trunk
/Users/david/projects/foo/trunk
/Users/david/projects/bar/trunk
/Users/david/projects/foobar/trunk
/Users/david/projects/barfoo/trunk
/Users/david/projects/foofoo/trunk
/Users/david/projects/trunk

real    0m4.09s
user    0m0.20s
sys     0m0.91s

find比使用globstar快四倍。此外,结果会在找到后立即返回。您最好使用find

$ find ~/projects -name trunk -type d -exec ack PATTERN {}\;