Crane
Table_bottom

Search
Loading
Table_bottom

分类
Table_bottom

随机文章
Table_bottom

标签云
Table_bottom

最新评论
Table_bottom

链接
Table_bottom

功能
Table_bottom

程序员兵器之代码搜索工具

Crane posted @ 2013年2月27日 20:29 in Linux with tags grep linux , 10089 阅读

工欲善其事,必先利其器。对于程序员来说,除却编辑器,编译器这些引起N多纷争的神器不谈,代码搜索无疑是个很常见的事情,有个趁手的工具那自然是极好的。

说起这个话题,老前辈grep(wiki)自然必须要首先说一说,grep当仁不让的奉献了N多年,伴随Unix而生,更是在如今的*nix系统中必占一席之地。grep由Ken Thompson操刀写成,名字取自ed编辑器的g/re/p命令,自1973正式服役以来,赢得众多好评,为Unix-like系统的文本处理一大利器。grep功能强大在于支持regular expression(如果不知道regular expression为何物,作为一个程序员,你摊上事了,不过想要精通regular expression,你又摊上一个大事),模式匹配使用了Boyer-Moore算法,并且对Boyer-Moore算法做了相当的优化,有一个GNU grep为什么如此快的文章详细介绍了这一个(看这里

事实上,作为每一个*nix系统必备的工具,有了grep和regex(regular expression简写),在搜索文本方面,几乎没多少困难了,更何况还有egrep(支持扩展的regex),zgrep(支持从压缩包匹配)等等更为强大的武装。而且掌握了这两大玩意,随便来一个*nix的系统,要从一堆文本中找出需要的东西应该都足够了。

但是,这么一个历史悠久,功能强大的工具也不能满足码农们日益增长的代码搜索需求,说大一点,正则表达式可以支撑绝大部分的文本匹配需求,但是复杂的正则表达式带来的是速度上的损耗,码农们日复一日的码代码,现在随便抓个代码库,都一大把的代码,更不要说像linux kernel这种重量级的codebase了,千万级的代码,想要找点什么东西不够快怎么行。快是一个方面,更好用也是一个很重要的方面,用户体验好,生产效率才高嘛。

有人的地方就有江湖,有程序员的地方就有需求。江湖路上没有永远的高手,昨日的高手是明日的英雄成名的基础。程序员为了能早点写完代码,去找找妹子,那自然要尽可能地追求各种效率,于是就有代表更强生产力的工具陆续出现在江湖。

首先出场,ack,掌声。。。

ack  grep-like text finder(项目主页

为什么要使用ack,它有什么优点呢?

ack用纯perl写成的脚本,这意味着任何支持perl的环境里都可以使用,安装方便,拷个文件就完事了。ack使用了高度优化的perl正则表达式,并且只搜索需要搜索的文件,略过那些备份文件,版本控制目录,而且支持只在一种语言的源文件中查找,而且输出结果更美观,比grep的要好看,还可以高亮搜索条目,重要的一点是,ack的参数和grep差不多,习惯grep的人能无缝切换到ack。噢,还有一点,ack打起来比grep快,哈哈。官方列出的why ack

ack能忽略版本控制目录或者只搜索一种语言的源文件很好用,试比较一下这两个场景

在一个svn版本库中搜索代码

$ grep pattern $(find . -type f | grep -v '\.svn')

$ ack pattern

只搜索perl源码文件

$ grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | grep -v .svn)

$ ack --perl pattern

比grep命令要节省时间,而且结果还更美观。

安装ack超级简单,有standalone版本(http://betterthangrep.com/ack-standalone),也可以使用发行版的包管理工具来搜索,或者参见这里(http://betterthangrep.com/install/)

ack是很强大(还有传说中的ack 2.0在开发中),但是江山代有才人出,一山更比一山高。一般情况下“但是”这个中国词一出,前面的都要悲剧。下一位选手the silver searcher更是力压ack大胜grep。

the silver searcher(后面简称ag,因为命令行是ag,哈哈,ag又比ack要好打),项目主页(https://github.com/ggreer/the_silver_searcher

ag的介绍语是

The Silver Searcher

  An attempt to make something better than ack (which itself is better than grep). 

据说比ack能快上3-5倍,还可以自定义忽略对象,而且,命令比ack要短33%,lol

为什么快?

1. 明文字符串使用Boyer-Moore-Horspool算法     

2. 使用mmap

3. 多线程

4. ……

具体可以参见:https://github.com/ggreer/the_silver_searcher/blob/master/README.md

ag是用C写的,需要pcre库的支持,源码可以从github的仓库获得。

这些都是说的,是骡子是马,还要拉出来溜溜才行,下面以kernel-3.6.11代码为例,来试试这几大武器。

$ time grep -r out_of_memory *

real    1m10.134s
user    0m0.153s
sys     0m8.576s

$ time grep  out_of_memory $(find . -type f | grep -v '\.git')

real    1m15.837s
user    0m0.557s
sys     0m9.379s

$ time ack out_of_memory

real    1m18.256s
user    0m4.870s
sys     0m12.683s

$ time ag out_of_memory

real    0m49.022s
user    0m0.550s
sys     0m10.309s

大致看一下,ack其实和grep差不多的,甚至grep还快一点,ack的优点就是使用方便,输出更直观,但是ag就是实打实的快很多了。so,the winner is ag。

PS:根据ag作者介绍,还有个git-grep,速度和ag差不多,但是只能在git仓库里面用。

update:更多类似工具,参见这里:http://betterthangrep.com/more-tools/

 

Avatar_small
依云 说:
2013年2月28日 00:01

最后的测试,grep 加上 -F 参数试试。

Avatar_small
Crane 说:
2013年2月28日 00:34

@依云: 会快一点,我的这个环境。
real 1m10.770s
user 0m0.300s
sys 0m8.613s

bamanzi 说:
2013年2月28日 14:20

还有一些:

* glark http://www.incava.org/projects/glark

* grin http://pypi.python.org/pypi/grin/

* rak http://rak.rubyforge.org/

我的介绍:

http://www.cnblogs.com/bamanzi/archive/2012/01/03/two-grep-replacement-or-supplement.html

http://www.cnblogs.com/bamanzi/archive/2012/08/21/another-grep-replacements-rak-grin.html

Avatar_small
Crane 说:
2013年2月28日 14:27

@bamanzi: 多谢分享,我看看

Avatar_small
λ 说:
2013年2月28日 18:18

不错的介绍~Thanks

星空™ 说:
2013年3月04日 16:11

vim那个插件,感觉还是没有cscope快

Crane 说:
2013年3月04日 16:12

@星空™: vim里面我用这个,global,感觉比cscope快,http://forum.ubuntu.org.cn/viewtopic.php?t=343460

星空™ 说:
2013年3月04日 17:12

昨天刚刚装上的时候的确很慢,刚刚试了下,是要快不少

Avatar_small
依云 说:
2013年3月04日 18:28

用上 ag 了,灰常好用。不过我还是喜欢 cgvg 啊,虽然慢了不少。

Avatar_small
星空™ 说:
2013年3月04日 20:35

@依云: 仙子不是一直五笔吗?! 今天这是?

Avatar_small
依云 说:
2013年3月04日 23:27

@星空™: 用五笔就不能卖萌了么喵?

Avatar_small
星空™ 说:
2013年3月05日 20:11

@依云: 好吧,你牛B。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter