我想使用bash的globstar
选项“**
”来搜索具有特定目录的文件,这与grep
一样习惯。但是,以下命令刚刚启动并且什么也没做
ack PATTERN ~/projects/**/trunk/
如何使用类似的搜索位置搜索ack
的文件?
编辑: 我尝试使用少量文件在模型目录上执行相同的行。它工作正常。因此,看起来运算符**
需要太多资源(我猜它有递归),当我执行命令时,它只是遍历文件树。顺便说一句,以下命令会降低计算机速度,这是我尝试ack
命令的原因。
grep -r PATTERN ~/projects/**/trunk/
所以,我想知道是否有一些解决方法可以实现我的目标(不一定是**
)?
答案 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
可能需要很长时间才能执行。您可能会发现,您甚至没有点击grep
或ack
返回匹配项的文件。你生命中的那段时间你已经浪费了,而且你永远不会回来。也可能看过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 {}\;