您的位置:首页 > 其它

[倚天屠龙记] vim 查找与替换(简单查找)

2015-06-04 17:57 253 查看
[倚天屠龙记] vim 查找与替换(简单查找) {{{

搜索与替换是文本编辑器的最重要的功能之一,也是其能力的一个缩影。

接下来用几节的篇幅重点叙述vim的查找与替换功能。

这一节只讲述vim的简单搜索功能,所谓简单,是相较于后续章节的正则表达式和高级查找替换而言的,这一节的主要内容是:基本的搜索命令/和?,单词搜索命令*和#,循环搜索,高亮搜索,增量搜索,历史搜索记录,整词匹配、大小写敏感开关,搜索时光标偏移,以及匹配总数统计,最后还有利用vimgrep在窗口中以链接的形式列出全部匹配结果并进行相应的跳转。要查看搜索命令的帮助文档请输入:help search-commands。

vim通用的搜索命令是左斜杠/和问号?,分别表示从光标所在位置向文件尾搜索和向文件头搜索,例如/hello和?hello分别表示向两个相反的方向搜索字符串hello,按下<Enter>键后光标会自动跳转到该字符串在当前搜索方向的第一次出现的位置(当然前提是能搜索到),按n键可以跳到下一个出现位置,而大写N键则跳到上一个出现位置,这里的上一个与下一个是就搜索的方向而言的,如果是使用?向文件头搜索,那么n就是向文件头方向的下一个,N是向文件尾方向的下一个。

在默认情况下,vim按照搜索方向到达了文件的一端,若继续搜索下一处,它会从文件的另一端继续开始搜索。在搜索若干次后必定会到达搜索操作开始时的第一次出现位置,此时已经对全文件搜索了一遍,继续搜索下一处则成了循环重复搜索,这个过程可以无限进行下去,为避免这一点,vim在搜索到文件的头部和尾部时会在屏幕下方提示已经到达了文件头或尾,接下来的搜索将从另一端开始。如果你希望在循环搜索一圈后又回到第一次搜索的位置停下来,你只有记住刚开始搜索时的行号,vim并不会提示你这一点。如果你希望vim在搜索到达文件的一端时,不必再从另一端开始搜索,可以通过:set
nowrapscan进行设置,这时vim只会在搜索到文件一端进行错误提示。

vim搜索时有一个高亮显示匹配文本块的功能,在按下<Enter>键后,文件中符合搜索串的文本都会进行高亮显示,这更容易引起你的注意力,这需要通过:set hlsearch或者:set hls来开启,hls即highlight search,也可以通过:st nohls来关闭。下面是在帮助文档中搜索字符串"search"的效果:




还有一个比较有用的功能就是增量搜索,它可以在你输入搜索串的过程中实时动态的进行搜索,比如你在输入hello的过程中,输入一个h后它会首先显示h的搜索结果,接着你输入e它又会重新显示he的搜索结果,依此类推,这在搜索串比较长的情况下非常有用,既可以防止你输入错误,也可以输入一半后找到匹配位置进行复制,然后重新按复制的内容进行搜索,关于寄存器的内容请参考《[倚天屠龙记] vim 复制与粘贴》一节中的介绍。要开启增量搜索,请使用:set incsearch 或者:set is,相应的,用:set noincsearch或者:set
nois进行关闭,通常把这个配置放到vimrc配置文件中以使其永久有效。

左斜杠寄存器/存储的是最近一次搜索的文本,如果想要查看近期的搜索历史可以使用q/和q?,分别代表近期分别使用/和?搜索的历史记录。

还有两个比较有用的搜索命令是*和#,当光标位于某个单词中时,按下*则会开始向文件尾的方向搜索该单词的下一个出现位置,然后使用n和N可以在下一个和上一个出现位置之间跳转,#与*的区别是,*是向文件尾的方向搜索,而#是向文件头的方向搜索,类似于/和?,即是说这两个命令只是固化了搜索的内容。*和#都是按单词进行搜索,如果有一行的内容同时含有单词for和forever,你把光标放在单词for上面按星号键,是不会搜索到forever中的前三个字符的,如果这是你想要的效果,请使用g*命令,它搜索时不会匹配整个单词,可以匹配单词的一部分,g#命令也具有同样的效果。

vim搜索时默认是大小写敏感的,要想实现大小写不敏感的搜索,如果仅仅是对当前打开的文件设置就用:set ignorecase,而永久性的设置可以到vimrc配置文件中添加一行

set ignorecase

然后重启vim即可生效,也可以通过:set noignorecase恢复大小写敏感的效果。此选项还有一个智能化的选择smartcase,它会根据你输入的模式串(要搜索的字符串)中是否包含大写字母来猜测你的意图,如果不含大写字母,它会关闭大小写敏感,只有在模式串中含有大写字母的情况下才启用大小写敏感,要使用此设置,请用:set ignorecase smartcase。如果你仅仅是想对某一次搜索时启用大小写敏感,则可以在搜索串的前面加上\C前缀,加用小写的\c前缀则是关闭大小写敏感,在搜索串中指定了\C或者\c时,全局性的大小写敏感开关ignorecase将不起作用,局部性的配置将优先得到使用。

在用左斜杠和问号命令进行搜索时,还可以添加一些标识位置的特殊字符,例如^代表行首,而$表示行尾,^123则只会匹配以行首的123,123$则只匹配行尾的123。\<匹配单词的开头,而\>匹配单词的结尾,利用这一点可以实现整词匹配的功能,利用\<for\>就匹配单词for,但是不会匹配forever的前三个字符。

默认情况下,vim在搜索过程中跳转到下一个出现位置时,光标是位于匹配的字符串第一个字符的,但是可以通过指定偏移量来改变这个默认行为,可以在搜索串后面上用左斜杠线或者问号分隔补上一个数字,就代表光标偏移的行数,例如 /default/2 代表搜索字符串default,但是每跳到一个匹配位置时,光标不是定位到default所在的行,而是该行下面第2行的行首,同样 ?default?-2 则是光标定位到default每次出现的上面第2行。除了基于行的偏移以外,还可以指定字符的偏移,分别用b和e代表匹配字符串的开头和结尾(即begin和end),/const/e
代表搜索字符串const时光标每次要跳到const中的t字符上,再跟上一个带正负号的数字则代表字符的偏移量,/const/e+2 代表跳到每一个const出现的结尾后面第2个字符处,而 ?const?b-5 则是跳到每一个const出现的前面第5个字符,要注意的是?改变的是搜索方向,并不会颠倒匹配字符串的顺序,即是说在 ?const?b+3 中,光标是定位到const每一次出现处的字符s处,而不是字符n处。

在搜索已经结束的情况下,如果想重复刚才的搜索,直接使用/或者?即可,它会重复上一次的/或者?搜索,不但会使用上一次的搜索文本,连偏移量也一并重复,换句话说,它会直接使用上一次搜索的一切定制行为。如果本次搜索只想要使用上一次的搜索文本,而偏移量的设置需要修改,例如上一次搜索是 /that,而本次搜索想要指定光标跳到匹配串的结尾,则可以使用 //e 进行搜索即可,即仅仅指定偏移量部分。如果上次指定了偏移量,而本次想取消偏移量的设置则直接使用 // 即可,余者类推。

在《[倚天屠龙记] vim 复制与粘贴》一文中,我介绍过一个特殊的寄存器:左斜杠寄存器/,它保存了最后一次搜索的文本内容,因此,如果想继续搜索上一次的文本,除了直接忽略搜索文本外,还可以在按下/后,按<C-R>再按左斜杠,寄存器/的内容就会自动出现在搜索命令中。

如果想要统计一个文本串的出现次数,这有点特殊,因为vim是用替换命令的统计功能来实现的,在这里只是作简单介绍一下,在后面讲解替换时再作详细说明。要在当前文件中统计字符串hello的出现次数的命令是:%s/hello/&/gn,其中s是替换命令,%表示当前文件,第一个和第二个左斜杠之间的内容是要被替换的内容,也就是旧的内容,第二个和第三个左斜杠是用于替换的内容,也就是新的内容,但&符号有特殊意义,它的意思是使用匹配的结果也就是旧的内容来进行替换,所以这其实就是个自我替换,而第三个左斜杠后面是替换相关控制参数,s命令是基于行来进行替换的,g表示行内的每一次出现都要进行替换,没有g则仅仅替换行内的第一次出现,而n则是报告替换操作的次数,所以在这个自我替换的情形下,它实际上就是字符串hello的出现次数,而且这个n有些特殊之处,只要设定了n参数,则替换操作实际上不会进行,仅仅报告有多少处文本需要进行替换,因此前面的用&来进行替换其实是不必要的,但是考虑到这个操作的危险性,万一少敲了这个n,那就是真正的替换了,所以最终的结论就是,为了保险起见,在统计某个字符串出现次数时最好用&进行替换。

可能有时候我希望列出一个字符串在全文中的所有匹配处的概要,以方便快速的定位想要编辑的地方,而无需反复的按下一处。在vim中可以通过内置的vimgrep来实现,假如想搜索字符串hello的全部出现位置,则使用命令:lvimgrep /hello/g% | lopen,这个命令比较长,以冒号打头,vimgrep是vim内置的grep(grep是linux的一个用于文本分析的标准命令行工具),加上l前缀是为了让其产生一个位置列表,/hello/g 表示搜索字符串hello,g参数是指明匹配行内的多次出现,没有它则匹配每一行的首次出现,百分号是指定搜索范围为当前文件,然后后面是用一个竖线分隔出了另一个命令lopen,lopen的作用是在一个新的缓冲区中列出当前缓冲区的位置列表,这个位置列表则来源于前面的搜索命令,以下是在一个日志文件中搜索字符串INVITE的结果:




可以看到,新缓冲区中列出了文件名、行数和列数,事实上,它还有链接的效果,先使用<C-W>j命令将光标移动这个窗口中(j表示向下),然后通过上下移动光标到列出的某一条搜索结果上,按回车键,则原文件窗口自动滚屏使这一行显示在屏幕上并且将光标定位到匹配之处,用这种方式可以查看文件中每一个匹配的地方。

}}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: