Jade Dungeon

vim

当前文件中查找替换

如果要替换, 就没有什么快捷键了. 一般的做法是

:%s/thisisaverylongword/ABCD/g  

同样,这还是要输入thisisaverylongword, 更简单的办法应该是:

把光标置于thisisaverylongword

之上, 然后

:%s/<CTRL+R><CTRL+W>/ABCD/g   

在命令格式下, CTRL+R代表插入寄存器, CTRL+W代表当前单词.

也可以通过寄存器的方式来使用. 使用v选择一个区域, 然后"ay , 存取寄存器a

然后

:%s/<CTRL+R>a/ABCD/g  

ABCD 可以用同样的方法,使用寄存器.

高亮显示查找结果

set hlsearch

区分大小写

:set ignorecase简写:set ic:set noignorecase:set noic

跨行查找

;表示查找跨行内容。 例如在以下文件中查找出现在字符串{file}+1后面的字符串echo

#!/bin/ksh
echo "Starting"
file=${1}
echo ${file}
if [[ ${file} = 1 ]] ; then
	((file=${file}+1))
	echo "Adding one gives " \
	${file}
fi
echo "Ending"
exit

应该使用/{file}+1/;/echo/,会查找到第10行。

用缩写替换

:ab <缩写> <要替换的文字>

例:

:ab asap as soon as possible

会把你输入的 「asap」 替换为 「as soon as possible」。

查找、修改、下一处、重复修改

找到指定内容后,普通模式下c w修改为想要的内容。

n到下一个匹配的内容,这时用.重复前面修改的操作。

删除括号内容:di

把光标放在括号、引号等符号上上,然后命令:

di[标记]

例:

清空圆括号:光标在括号上,然后:

di(

清空括号:光标在括号上,然后:

di[

清空花括号:光标在括号上,然后:

di{

清空双引号:光标在括号上,然后:

di{

删除到目标内容:dt

删除的是光标到指定符号的内容:

dt[标记]

例:

abcdefghijklmnopqrstuvwxyz
     ^

光标在f的话,命令dtr的结果是:

abcderstuvwxyz
     [[^]]

重新放置搜索模式

就是把要替换的搜索结果放在缓冲区内,在替换时可以通过缓冲区引用号重新放置它们。 方法:

\(模式\)

上面的格式会把模式放在编号的缓冲区(1 到 9)中。在执行替换时,可以用缓冲区引用号:

\1 到 \9 

引用这些缓冲区。

例如,假设要在下面所示的文件中:

Martin is an IT consultant. Martin likes
snowboarding and mountain biking. Martin has
worked on UNIX systems for over 15 years. Martin also
worked for many years before that on mainframes.
Martin lives in London.

搜索以单词Martin开头的行并对每个匹配添加前缀Mr和后缀Wicks, 那么进入命令模式:

:%s/^\(Martin\)/Mr \1 Wicks/g

对上面命令的解释:

  • :%s: 指示vi 执行替换。
  • /: 模式分隔符。
  • ^\(Martin\): 寻找以字符串 Martin 开头的行并把这个字符串保存在缓冲区 1 中。
  • /: 模式分隔符。
  • Mr \1 Wicks: 把找到的字符串替换为字符串 Mr,加上缓冲区 1 中的内容,再加上字符串Wicks
  • /: 模式分隔符。
  • g: 全局修改(即修改所有匹配的地方)
  • c: 交互,每个替换位置由用户确认。

跨文件查找

grep

vim既可以使用外部的grep程序,也可以使用内部集成的grep功能。

使用集成的grep命令非常简单,通常使用格式为:

:vimgrep /main/gj **/*.c 

在上面的例子里,我们使用vim内部集成的grep功能,在当前目录及其子目录树的所有 c文件中查找main字符串,如果一行中main出现了多次,每个匹配都计入;在查找 到后,不立即跳转到第一个匹配的地方。

使用内部集成的grep功能速度要比外部grep慢一些,因为它会打开每个文件,对其进行 检查,然后关闭;但集成的grep支持vim增强的正则表达式,可以利用它进行更为复杂的 查找。它也支持vim扩展的文件通配符表示方式,见:help starstar-wildcard

vimgrep查找到的结果,也会放在quickfix列表中。

你也可以用外部的grep程序来查找,如果你的系统中所用的不是标准的grep程序,那么就 需要修改grepprg选项,详情请参阅手册。

使用外部grep的语法与grep程序相同,请参阅grep的手册。

无论使用内部的vimgrep,还是使用外部的grep,vim都允许你将查找到的结果放在与窗口 相关联的位置列表,要了解详细信息,:help :lvimgrep:help :lgrep

在我的vimrc中,定义下面的键映射,利用它可以在当前文件中快速查找光标下的单词:

nmap <leader>lv :lv /<c-r>=expand("<cword>")<cr>/ %<cr>:lw<cr> 

例子

查找重复的单词

\(\<\w\+\>\)\_s*\1

删除空白行

:g/^$/d

换行符

替换^M字符

:%s/^M$//g # 去掉行尾的^M。
:%s/^M//g # 去掉所有的^M。
:%s/^M/[ctrl-v]+[enter]/g # 将^M替换成回车。
:%s/^M/\r/g # 将^M替换成回车。

注意:这里的^M要使用CTRL-V CTRL-M生成,而不是直接键入^M

Vim删除偶数行或者奇数行

删除偶数行的方法如下:

:g/^/+1 d

上面用到了:gbobal命令,gbobal命令格式如下:

:[range]global/{pattern}/{command}

global命令实际上是分成两步执行:

  1. 首先扫描[range]指定范围内的所有行,给匹配{pattern}的行打上标记;
  2. 然后依次对打有标记的行执行{command}命令,如果被标记的行在对之前匹配行的 命令操作中被删除、移动或合并,则其标记自动消失,而不对该行执行{command}命令 。{command}可以是一个ex命令,也可以是用|分隔的多个ex命令,这样我们就可以 对被标记行,或从标记行寻址到的行进行多种不同的操作。

上面删除偶数行的命令,先匹配所有行,然后隔行删除(其中+1用以定位于当前行的 下一行)。为什么是隔行呢?因为在对第一行执行+1d命令时删除的是第二行,而第二行 虽然也被标记了,但已不存在了,因此不会执行删除第三行的命令。

删除几数行的命令如下:

:g/^/d|m

其中m的作用是移出偶数行的标记,防止偶数行也被删除。

另外删除奇数行偶数行,也可以用normal命令,分别为(第一个命令为几数行):

:%norm jkdd
:%norm jdd