7
18
2014
11

搜索,快人一步

本文来自依云's Blog,转载请注明。

缘起

在一群文件里搜索特定的文本,第一个想到的工具是经典的 grep。自从知道 ag——The silver searcher 之后,我就只在命令行管道里用 grep 啦。

ag 的优势:

  • 命令短
  • 和 ack 以及 git grep 一样,默认会忽略掉你通常不想看的文本(二进制文件、被版本控制系统忽略掉的文件)
  • C 编写的,比 ack 更快!

作者挺在乎程序的执行效率。这也很重要,因为文件多啊,几十上百兆的源码找起来可费时了。

不过在我这里,ag 取代掉的既不是 grep 也不是 ack。因为我之前用的是 cgvg,和 ack 一样也是 Perl 写的,但不一样的是,它包含两个命令:一个(cg)用来搜索,另一个(vg)用来在编辑器里打开!

不知道为什么其它工具的作者都没有想到这一点。匹配的地方找到了,大部分情况都需要用编辑器打开看看,也许再改改吧?cgvg 免去了复制路径到编辑器里并跳转到特定位置这一烦琐的步骤。

所以换用 ag 之后,我自然也希望能够很便利地使用编辑器查看匹配的地方了。为此,我做了三个工具。好吧,其实有一个是在 cgvg 时代就已经有了的。

搜索

实践一下。假设我要寻找 Vim 源码中涉及到p_enc变量的地方。使用 agg 命令来搜索并使用翻页器 less 显示结果(截图时没有显示出 less 的存在):

agg result

agg 脚本更改了 ag 的显示样式,每一项开头都有一个序号,就和 cg 命令一样。同样地,agg 也把这个结果保存在主目录下的一个文件,以供 agv 命令使用。

注意,agg 并不能用来按文件名搜索。这种情况还是用 ag -g pattern

使用编辑器打开

agv 命令不给定参数,会显示上一次搜索的结果。如果给出一个编号,就会将结果在AGV_EDITOR环境变量指定的编辑器里打开,并跳转到对应的地方。和 vg 不同的是,agg/agv 为每一个终端维护了一个结果列表,这样就可以在不同的终端里搜索不同的内容而不会相互干扰了。

比如我们要去第 14 号结果所在的地方,只要执行agv 14,然后就到了:

agv result

我这里是在已有的 gVim 里打开的哦。因为我设置的AGV_EDITOR的值是vv $file:$line:$col。这是一句包含占位符的 shell 命令。$file$line$col分别是结果所在的文件、行号、列号。而vv,则是我写的另一个工具,用来在已经打开的 gVim 里打开文件,并且跳转到特定的地方

vv 需要 Python easygui 库,以及 gVim(或者 Vim)的 +clientserver 支持。vv 不仅支持上述格式的参数,作为一名 Pythonista 所编写的工具,它也支持从 Python 报错时打印的 Traceback 的行中提取文件名和行号。比如:

vv 'File "/usr/lib/python3.4/sre_parse.py", line 358, in _parse_sub'

这里,不一定要复制一整行。包含必要的信息(文件名和行号)就可以了。

当然,手动复制粘贴比较累。所以配合我的 zsh 全局别名:

alias -g XS='"$(xsel)"'

我只需要选中那一行,然后执行

vv XS

就可以了。zsh 会帮我把XS展开成我刚刚选择的文本。

ag.vim

ag.vim 是一个 ack.vim 的修改版,用于在 Vim 中调用 ag,就像 ack.vim 在 Vim 中调用 ack、grep.vim 在 Vim 中调用 grep 一样。

因为经常搜索在当前光标下的内容,我写了这么一条自定义命令:

command Agg exe 'Ag -Q ' . expand('<cword>')

仓库地址

https://github.com/lilydjwg/search-and-view

Category: Linux | Tags: python grep AG | Read Count: 11234
Iven 说:
Jul 19, 2014 10:00:32 AM

……你造轮子了……搜一下 sack 和 ctrlsf 吧……

Avatar_small
依云 说:
Jul 19, 2014 11:44:30 AM

ctrlsf 我不太喜欢。我没有那么大的空间放它那个垂直分割的结果窗口。

至于 sack,那个 profiles 我不知道有什么用,特别是对于一个 autojump + zsh 用户。它在不同终端中不能使用不同的结果集。修改 $PATH 中的文件也不是什么好主意。它支持的编辑器也有限,并且无法跳转到结果所在的列。

所以如果要算造轮子的话,那也是造了一个更适合自己的轮子。

尹良灿 说:
Jul 21, 2014 05:45:36 PM

有时 Traceback 显示的文件会是相对路径(比如直接 python a.py 的时候),可不可以让 vv 如果没有绝对路径时自动根据当前终端的工作路径来获取文件呢?

尹良灿 说:
Jul 21, 2014 05:47:42 PM

对不起。。。。。

尹良灿 说:
Jul 21, 2014 06:00:46 PM

原来是支持的。。。不过有点错误:

In [3]: vv.parseLineno('File "test.py", line 3')
Out[3]: ('+3', '/home/xxx/Documents/Programming/python/search-and-view/y')

清水 说:
Jul 24, 2014 10:39:08 PM

太高端了,这是命令行的vim吗?我用了一下命令行的vim版本感觉自己简直无从下手。。

Avatar_small
依云 说:
Jul 25, 2014 12:05:56 PM

前边那个截图是终端,后一个是 gvim。

Avatar_small
依云 说:
Jul 25, 2014 12:06:44 PM

Vim 需要时间学习的。你可以在终端里执行 vimtutor 然后就有教程了。

dyng 说:
May 31, 2015 03:57:11 PM

ctrlsf现在可以水平放置窗口,也可以调整大小了。

ctrlsf因为浏览可以使用预览模式,编辑也基本可以通过(最近新加的)编辑模式完成,90%的情况下不需要(在开着ctrlsf窗口的情况下)离开ctrlsf窗口,所以才把默认的体积设定得比较大。如果作为quickfix窗口的替代品来用的话可能确实不太好用。


登录 *


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

| Theme: Aeros 2.0 by TheBuckmaker.com