1

我想使用bash 的globstar选项 ' **' 来搜索具有特定目录的文件,就像习惯上与grep. 但是,下面的命令刚刚启动,什么也没做

ack PATTERN ~/projects/**/trunk/

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

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

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

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

4

2 回答 2

2

这应该有效:

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

-X论据,来自find手册

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

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

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

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

于 2014-12-23T15:25:39.253 回答
1

shell 会扩展**——也就是说,如果您首先设置shopt -s globstar 使用 Bash 4.0 或更高版本。在这种情况下,您可以查看 shell 与您的globstar. 试试这些:

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

或者:

$ echo ~/projects/**/trunk/

然后,去喝杯咖啡,因为globstar可能需要很长时间才能执行。您可能会发现您甚至没有点击grepack返回匹配的文件。那是你生命中的几分钟,你已经浪费了,你将永远不会回来。还不如看过星球大战假期特辑。至少,你可以制作某种饮酒游戏。

问题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 {}\;
于 2014-12-23T15:55:41.013 回答