*usr_12.txt* For Vim version 7.0. 最近更新:2006年5月
Vim用户手册 - Bram Moolenaar
译者
:Nek_in http://vimcdoc.sf.net
小窍门
通过组合一些命令,你可以用 Vim 完成几乎所有的工作。本章将介绍一些有用的命令组
合。涉及的命令大都是前面章节介绍过的,但也会有一点新命令。
|12.1| 单词替换
|12.2| 把 "Last, First" 改成 "First Last"
|12.3| 排序
|12.4| 反排行顺序
|12.5| 单词统计
|12.6| 查阅 man 信息
|12.7| 删除多余空格
|12.8| 查找单词的使用位置
下一章:|usr_20.txt| 快速键入命令行命令
前一章:|usr_11.txt| 从崩溃中恢复
目录:|usr_toc.txt|
*12.1* 单词替换
替换命令可以在全文中用一个单词替换另一个单词::%s/four/4/g
"%" 范围前缀表示在所有行中执行替换。最后的 "g" 标记表示替换行中的所有匹配点。 如果你有一个象 "thirtyfour" 这样的单词,上面的命令会出错。这种情况下,这 个单词会被替换成"thirty4"。要解决这个问题,用 "\<" 来指定匹配单词开头:
:%s/\<four/4/g
显然,这样在处理 "fourty" 的时候还是会出错。用 "\>" 来解决这个问题:
:%s/\
<four\>
/4/g如果你在编码,你可能只想替换注释中的 "four",而保留代码中的。由于这很难指定, 可以在替换命令中加一个 "c" 标记,这样,Vim 会在每次替换前提示你:
:%s/\
<four\>
/4/gc
在 多 个 文 件 中 替 换 假设你需要替换多个文件中的单词。你的一个选择是打开每一个文件并手工修改。另外, 如果使用 "记录-回放" 命令会更快。 假设你有一个包括有 C++ 文件的目录,所有的文件都以 ".cpp" 结尾。有一个叫 "GetResp" 的函数,你需要把它改名为 "GetAnswer"。 vim *.cpp 启动 Vim,用当前目录的所有 C++ 文件作为文件 参数。启动后你会停在第一个文件上。 qq 用 q 作为寄存器启动一次记录。 :%s/\
<GetResp\>
/GetAnswer/g 在第一个文件中执行替换。 :wnext 保存文件并移到下一个文件。 q 中止记录。 @q 回放 q 中的记录。这会执行又一次替换和 ":wnext"。你现在可以检查一下记录有没有错。 999@q 对剩下的文件执行 q 中的命令 Vim 会在最后一个文件上报错,因为 ":wnext" 无法移到下一个文件上。这时所有的文件 中的操作都完成了。备注
: 在回放记录的时候,任何错误都会中止回放的过程。所以,要注意
保证记录中 的命令不会产生错误。 这里有一个陷阱:如果有一个文件不包含 "GetResp",Vim 会报错,而整个过程会中止, 要避免这个问题,可以在替换命令后面加一个标记::%s/\
<GetResp\>
/GetAnswer/ge"e" 标记通知 ":substitute" 命令找不到不是错误。
*12.2* 把 "Last, First" 改成 "First Last"
你有如下样式的一个名字列表:Doe, John
Smith, Peter
你想把它改成:John Doe
Peter Smith
这可以用一个命令完成::%s/\([^,]*\), \(.*\)/\2 \1/
我们把这个命令分解成几个部分。首先,很明显它是一个替换命令。"%" 是行范围, 表示作用与全文。这样替换命令会作用与全文的每一行。 替换命令的参数格式是 "from/to",正斜杠区分 "from" 模式和 "to" 字符串。 所以,"from" 部分是:
\([^,]*\), \(.*\)
第一对\(和\)之间的部分匹配"Last" \( \) 匹配除逗号外的任何东西 [^,] 任意多次 * 匹配逗号 , 第二对\(和\)之间的部分匹配"First" \( \) 匹配任意字符 . 任意多次 * 在 "to" 部分,我们有 "\2" 和 "\1"。这些称为 "回溯索引"。它们指向前面模式中 的\(和\)间的部分。"\2" 指向样式中的第二对\(和\)间的部分,也就是 "First" 名 (译者注
:英文中 Last Name 表示姓,即家族名,后面的 First Name 表示名字)。 "\1" 指向第一对\( \),即 "Last" 名。 你可以在替换部分使用多达 9 个回溯索引。"\0" 表示整个匹配部分。还有一些 特殊的项可以用在替换命令中。请参阅|sub-replace-special|。
*12.3* 排序
在你的 Makefile 中常常会有文件列表。例如:OBJS = \
version.o \
pch.o \
getopt.o \
util.o \
getopt1.o \
inp.o \
patch.o \
backup.o
要对这个文件列表排序可以用一个外部过滤命令:/^OBJS
j
:.,/^$/-1!sort
这会先移到 "OBJS" 开头的行,向下移动一行,然后一行行执行过滤,直到遇到一个空 行。你也可以先选中所有需要排序的行,然后执行 "!sort"。那更容易一些,但如果有 很多行就比较麻烦。 上面操作的结果将是:
OBJS = \
backup.o
getopt.o \
getopt1.o \
inp.o \
patch.o \
pch.o \
util.o \
version.o \
注意
,列表中每一行都有一个续行符,但排序后就错掉了!"backup.o" 在列表的最后, 不需要续行符,但排序后它被移动了。这时它需要有一个续行符。 最简单的解决方案是用 "A \<Esc>
" 补一个续行符。你也可以在最后一行放一个续 行符,由于后面有一个空行,这样做是不会有问题的。
*12.4* 反排行顺序
|:global| 命令可以和 |:move| 命令联用,将所有行移动到文件首部。结果是文件被按 行反转了次序。命令是:
:global/^/m 0
缩写:
:g/^/m 0
正则表达式 "^" 匹配一个行首 (即使该行是一个空行)。|:move| 命令将匹配的行移动 到那个神秘的第0行之后。这样匹配的行就成了文件中的第一行。由于 |:global| 命令 不会被改变了的行号搞混,该命令继续匹配文件中剩余的行并将它们一一变为首行。 这对一个行范围同样有效。先移动到第一行上方并做标记 't' (mt)。然后移动到范围 的最后一行并键入:
:'t+1,.g/^/m 't
*12.5* 单词统计
有时你要写一些有最高字数限制的文字。Vim 可以帮你计算字数。 如果你需要统计的是整个文件的字数,可以用这个命令:g
CTRL-G
不要在 "g" 后面输入一个空格,这里只是表示用两个命令。 它的输出是:
Col 1 of 0; Line 141 of 157; Word 748 of 774; Byte 4489 of 4976
(译者注
:中文是:列 1/0; 行141/157; 字(Word) 748/774; 字符(Byte) 4489/4976
) 你可以看到你在第几个单词(748)以及文件中的单词总数(774)。 如果你要知道的是全文的一部分的字数,你可以移到该文本的开头,输入 "gCTRL-G
", 然后移到该段文字的末尾,再输入 "gCTRL-G
",最后心算出结果来。这是一种很好的 心算练习,不过不是那么容易。比较方便的办法是使用可视模式,选中你要计算字数的 文本,然后输入 "gCTRL-G
",结果将是:Selected 5 of 293 Lines; 70 of 1884 Words; 359 of 10928 Bytes
要知道其它计算字数,行数和其它东西总数的方法,可以参见 |count-items|。
*12.6* 查阅 man 信息 *find-manpage*
编辑一个脚本文件或者 C 程序的时候,有时你会需要从 man 手册中查询某个命令或者 函数的用法(使用 Unix 的情况下)。让我们先用一个简单的方法:把鼠标移到对应的 单词上然后输入:K
Vim 会在对应的单词上执行外部命令:man。如果能找到相应的手册,那个手册页就会被 显示出来。它常常用 more一类的程序显示页面。在手册滚动到文末并回车,控制就会回 到 Vim 中。 这种方法的缺点是你不能同时查看手册和编辑文档。这里有一种办法可以把手册显示到 一个 Vim 的窗口中。首先,加载 man 文件类型的外挂:
:runtime! ftplugin/man.vim
如果你经常用到这种方法,可以把这个命令加到你的 vimrc 文件中。现在你可以用 ":Man" 命令打开一个显示 man 手册的窗口了:
:Man csh
你可以在这个新的窗口中上下滚动,而手册的本文会用语法高亮的形式显示。这样,你可 以找到需要的地方,并用
CTRL-W
w 跳转到原来的窗口中继续工作。 要指定手册的章节,可以在手册名称前面指定。例如,要找第三章的 "echo"::Man 3 echo
要跳转到另一个由 "word(1)"形式定义的手册,只要在上面敲
CTRL-]
。无论怎样, ":Man" 命令总使用同一个窗口。 要显示当前光标下的单词的手册,这样:\K
(如果你重定义了
<Leader>
,用那个字符代替上面命令的反斜杠)。 例如,你向知道下面语句中的 "strstr()" 函数的返回值:if ( strstr (input, "aap") == )
可以把光标移到 "strstr" 并输入 "\K"。手册使用的窗口会显示 strstr() 的信息。
*12.7* 删除多余的空格
有些人认为行末的空格是无用,浪费而难看的。要删除这些每行后面多余的空格,可以 执行如下命令::%s/\s\+$//
命令前面指明范围是 "%",所以这会作用于整个文件。"substitute" 命令的匹配模式是 "\s\+$"。这表示行末($)前的一个或者多个(\+)空格(\s)。后面我们会介绍怎样 写这样的模式。|usr_27.txt|。 替换命令的 "to" 部分是空的:"//"。这样就会删除那些匹配的空白字符。 另一种没有用的空格是 Tab 前面的字符。通常这可以删除而不影响格式。但并不是总这 样!所以,你最好手工删除它。执行如下命令:
/
你什么都看不见,其实这是一个空格加一个 TAB 键。相当于 "/
<Space>
<Tab>
"。现在, 你可以用 "x" 删除多余的空格,并保证格式没有改变。接着你可以用 "n" 找到下一个 位置并重复这个操作。
*12.8* 查找单词的使用位置
如果你是一个 UNIX 用户,你可以用 Vim 和 grep 命令的组合来完成编辑包括特定单词 的所有文件的工作。这在你编辑一个程序而且想查看和编辑看所有的包括使用某个变量 的文件的时候非常有用。 举个例子,假设想编辑所有包括单词 "frame_counter" 的 C 源文件,你可以执行 如下命令:vim `grep -l frame_counter *.c`
让我们分析一下这个命令。grep 从一组文件中查找特定的单词。由于指定了 -l 参数, grep 只列出文件而不打印匹配点。被查找的单词是 "frame_counter",其实这可以是 任何正则表达式。(
注意
:grep 所使用的正则表达式与 Vim 使用的不完全一样)。 整个命令用反引号(`)包起来,这告诉 UNIX 的 shell 使用该命令的输出作为命 令行的一部分。于是,grep 命令产生一个文件列表,并作为 Vim 的命令参数。Vim 将 编辑 grep 列出来的所有文件。你可以通过 ":next" 和 ":first" 命令一个一个处理 这些文件。 找 到 每 一 行 上面的命令只是找到包括单词的那个文件。你还需要知道单词在该文件中出现的地方。 Vim 有一个内置的命令用于在一组文件中找一个指定的字符串。例如,如果你想在所 有的 C 文件中查找 "error_string",可以使用如下命令::grep error_string *.c
这会使 Vim 在所有指定的文件 (*.c) 中查找 "error_string"。Vim 会打开第一个匹配 的文件并将光标定位在第一个匹配行。要到下一个匹配行(无论在哪个文件),可以执行 "cnext" 命令。要回到上一个匹配行,可以用 ":cprev" 命令。使用 "clist" 可以看到 所有的匹配点。 ":grep" 命令会使用一个外部的程序。可能是 grep(在 Unix 上)或者 findstr(在 Windows 上)。你可以通过 'grepprg' 选项修改这个选项。
下一章: |usr_20.txt| 快速键入命令行命令 版权:参见|manual-copyright| vim:tw=78:ts=8:ft=help:norl:
Generated by vim2html on 2006年 06月 24日 星期六 00:27:59 UTC