本章学习vi编辑器中的全局替换命令。通过全局替换命令,可以自动替换文件中所有出现过的某个单词。全局替换一般会用到两个ex命令:":g"(global),":s"(substitute)。
替换命令:
替换命令的语法如下: " :s/old/new/ ",该命令会将当前这一行中第一个出现的old模式替换为new。其中斜线用来分隔命令的各部分(如果斜线位于该命令的最后一个字符,则该斜线可以省略)。
" :s/old/new/g "会将当前这一行中的所有old模式替换为new。在s前面加上行地址,就可以指定替换命令将会影响的行范围。例如 : " %s/old/new/g "就能将文件中所有的old模式替换为new,如下图所示:该命令将文件中的所有line替换为file。
而以下命令只会将文件所有行中的第一个line替换为file:
确认替换:
在使用搜索和替换命令时,应该非常小心。可以在替换命令的结尾加上c选项(代表confirm),从而在每一次替换之前进行确认,如下图所示:
此时输入y(代表"yes")即可对当前匹配的到的字符串进行替换,而输入n则不进行替换。
与上下文有关的替换:
有时,需要搜索一个模式,当找到包含该模式的某个行时,将该行中的另一个字符串进行替换。即搜索模式并不是需要被替换的字符串。此时可以通过如下命令实现 " :g/pattern/s/old/new/g "。其中第一个g代表对文件中的所有行起作用,而最后一个g代表将每行中的所有old都替换为new(如果没有这个g,则只会对每一行中的第一个old进行替换),patten即为搜索模式。
如下图所示:该命令将搜索所有包含" Line "模式的行,并将该行中的 "this "字符串替换为" that "。
当用于搜索的模式和用于替换的模式一样时,就没有必要重复输入了。此时可以简写为 " :g/string/s//new/g ",该命令和 ":%s/string/new/g"命令效果一样。
模式匹配的规则:
除了可以搜索常量字符串,vi编辑器还可以搜索可变的模式,即正则表达式。正则表达式是一种将普通字符和特殊的元字符结合起来的表达式。
用在搜索模式中的元字符:
. (点号):匹配任何一个单一字符(除换行符外);
* :匹配0到无穷多个前一个字符,因此 .* 即可匹配出任何数量的任何字符;
^:当^出现在正则表达式的开头时,代表后面的正则表达式内容必须出现在一行的开头。如果^不是出现在正则表达式的开头,则没有特殊含义;
$:当$出现在正则表达式的结尾时,代表前面的正则表达式内容必须出现在一行的结尾。如果$不是出现在正则表达式的结尾时,则没有特殊含义;
\ : 相当于转义字符,将后面的特殊字符当成一般的字符。
[ ]:匹配出方括号里的任何一个字符。例如p[aeu]t 匹配中pat,pet,put。而且如果匹配目标为一个范围的字符,则可用第一个字符加上连字符,再加上最后一个字符来表示。例如,[A-Z] 匹配出A到Z之间的大写字母,[0-9]匹配出0到9内的任何数字。而且方括号内可以包含两个以上的范围,也可以混合使用范围和单个字符。插入符号^作为方括号内的第一个字符时,表示匹配出任何一个不在方括号中字符范围内的字符。
\(\):会将 \( 与 \) 之间的模式保存到特殊的空间(称为保留缓冲区)。这种方法可以保存任何一行中的9个模式。
\< \> 会匹配出以某些字符开头(\<)或结尾(\>)的单词;
~:会匹配出上一次搜索时所使用的正则表达式。
POSIX方括号表达式:
方括号除了可以用于匹配出位于方括号内的任何一个字符,POSIX引进了另外的方法,用于比较非英文字母的字符。在POSIX标准中,方括号内的字符组称为“方括号表达式”。方括号表达式中,除了可以有文字字符,还可以包括其它元素:字符类:POSIX字符类包括了用 [: 与 :] 括起来的关键字。
校对符号:校对符号是由多个字符组成的序列,但是必须被当成一个单位。并且使用 [. 与 .]括起所需字符。
等价类:等价类列出所有应该被当成相等的字符集合,用[=与=]括起来。
这三类都必须出现在方括号表达式中,例如 [[:alpha:]!] 匹配出任何一个字母字符或者感叹号。具体的POSIX字符类型可以参看《vi和vim编辑器》第六章:全局替换。
用在替换字符串中的元字符:
当做全局替换时,前面提到的具有特殊意义的元字符只能用在命令的搜索部分,即第一部分。而在替换字符串部分,这些元字符可能就失去了特殊意义。例如下图中的命令只会将A或B或C都替换为"[abc]",而不是相应的小写字母。
但是在替换字符串中,仍然存在一些具有特殊意义的元字符。
\n:利用 \( 与 \) 存储的第n个模式做文本替换;
\:和搜索模式中的 \ 字符含义相同,都是转义字符,使后面的一个特殊字符变为普通字符,从而失去特殊含义;
&:当用在替换字符中,&会被替换为搜索模式匹配出的完整文本,这在避免重复输入文本时很有用;
~:和搜索模式中的~元字符意义类似,用来代表最后一个替换命令中的替换文本。这在重复编辑时很有用;
\u或\l:使替换字符串中的下一个字符变成大写或小写;
\U或\L或\e或\E:\U或\L会使后面的所有字符都被转化成大写或小写的,直到出现\e或\E为止。
更多替换技巧:
:s:等同于 :s//~/,即会重复上一次替换;
:& : 也能重复上一个替换,可以把&想象成" 同样的东西 ";
:~ :与:&命令类似,但是用来搜索的模式是上一个出现的正则表达式,而不是上一个替换命令中使用的正则表达式。
除了使用 / 字符作为替换命令中的分隔符,还可以使用任何非字母,非数值,非空格的字符,但是反斜线,双引号,和竖线除外,这在对路径字符串做替换时非常有用。
本章vi命令总结:
:s/old/new,g选项,c选项,:g,
搜索模式中的特殊字符 ., *, ^, $, [], \(\), \<, \>, ~,
替换模式中的特殊字符 \n,\, &,~, \u, \l,\U,\L, \e,\E,
:s, :&, :~。