2011-06-16 wcdj
(一) 确认替换
(二) 上下文相关替换
(三) 模式匹配规则
(1) 元字符在搜索模式中的使用
(2) 一些模式匹配例子
全局替换真正使用的是两个 ex 命令 —— :g(全局)和 :s(替换)
替换命令的语法 如下:
(1)
: s/old/new/ 这将把当前行中模式 old 的第一次出现修改为 new
/(斜杠)是命令不同部分之间的分隔符(当斜杠为该行的最后一个字符时,它是可选的)。
(2)
: s/old/new/g 把当前行old的每次出现改为new,而不只是该行的第一个old
:s 命令允许替换后面带有选项,上面语法中的 g 选项代表全局(注意:g 选项影响一行中的每个模式,不要把它与影响文件中所有行的 :g 命令混淆)。
(3)
: 50 , 100 s/old/new/g 通过在 :s 命令前面加上地址前缀,可以把它的范围扩展到多行
: 1 , $ s/old/new/g 将把整个文件中的old的每次出现改为new
: % s/old/new/g 也可以使用 % 代替 1 , $ 来指定文件中的每一行
全局替换要比分别寻找并替换字符串的每个实例快的多。由于该命令可以进行不同类型的修改,并且它的功能非常强大。
(一) 确认替换
使用搜索替换命令时一定要非常仔细,有时得到的结果并不是想要的。可以通过输入 u 来取消任何搜索替换命令,前提是该命令是最后进行的编辑操作。但是并不是总能在还可以恢复的时候就发现意外的修改。另一个保护所编辑的文件的办法是在进行全局替换前使用 :w 保存文件。这样至少可以不保存编辑而退出文件,然后再返回文件修改前的状态。你还可以使用 :e! 读取缓冲区的先前版本。
如果想在替换前看到搜索结果和确认每个替换,则可以在替换命令的尾部加上 c 选项 (用于确认):
: 1 , 30 s/his/the/gc 会逐一确认替换,如果想替换该字符串,必须输入 y(代表是)并按下 RETURN 键;如果不想替换,则只需按下 RETURN 即可。(???尝试下,发现自己安装的版本不一样。替换时,按 y 即可;不替换时,按 n 即可,不需要按 RETURN)
注意:
vi 的 n(重复上次搜索)和点(.)(重复上次命令)命令的结合也是一种极为有用的方法,它可以快速地在文件中翻页来执行不想全部替换的修改。
例如:如果在该使用 that 的时候使用了 which,那么可以抽查 which 的每次出现,只修改那些不正确的:
/which 搜索 which
cwthat+ESC 修改为 that
n 重复搜索,跳过一次修改
n 重复搜索,跳过一次修改
. 修改为 that,使用 . 命令重复修改
……
(二) 上下文相关替换
最简单的全局替换是使用一个单词(或短语)替换另一个。还有稍微有点复杂的全局替换语法,这些语法可以对一个模式进行搜索,一旦找到含有模式的行,就可以使用不同于模式的串进行替换,把这种替换看作 —— 上下文相关替换。
:g /pattern/ s/old/new/g
第一个 g 是在文件的所有行上执行的命令,模式 pattern 识别要发生替换的行。在那些包含模式 pattern 的行上,ex 将把old替换(s)为 new。最后的 g 表示在该行上进行全部替换。
如果用来进行搜索的模式与想要修改的模式相同,那么就不必重复它。例如:
:g /string/ s//new/g 等价于
:g s/string/new/g 等价于
:% s/string/new/g
将搜索包含string的行,并将string替换为new。
(三) 模式匹配规则
在进行全局替换时,类似于 vi 的 UNIX 编辑器允许你搜索的不只是固定的字符串,还允许搜索由正则表达式指代的可变的单词模式。
正则表达式由普通字符和许多称为元字符的专用字符结合在一起组成。
(1) 元字符在搜索模式中的使用
. 匹配除换行符之外的任何一个单个字符
* 匹配其前面的单个字符的0个或多个实例
^ 以什么开始,当^不在正则表达式的开始时,^只代表本身
$ 以什么结尾,当$不在正则表达式的结尾时,$只代表本身
/ 将后面的专用字符看成普通字符,/(反斜杠)会防止对专用字符的解释。例如,/. 与一个真正的点匹配,而不是“任何单个字符”
[ ] 匹配方括号所包括的字符中的任何一个。例如,[AB] 匹配A或B。
注意:
(1) 可以通过使用连字符分开该范围的首尾字符来指定连续的字符范围。例如,[A-Z] 将匹配A到Z之间的任何一个大写字母,[0-9] 将匹配0到9之间的任何一个数字。
(2) 可以在方括号内包含多个范围,也可以把范围和单独的字符混合在一起。例如,[:;A-Za-z()] 将匹配4种不同的标点符号和所有的字母。
(3) 大部分元字符都将在方括号内失去它们的特殊含义,因此不需要转义,在方括号内,仍需要转义的3个元字符是 /、- 和 ] 。
(4) 插入符号(^)只有它在方括号内为第一个字符时才有特殊含义,但是在这种情况下其含义与通常 ^ 元字符的含义不同。作为方括号的第一个字符,^ 使它们的含义反过来:方括号将匹配不在列表内的任何一个字符。例如,[^a-z] 将匹配任何不是小写字母的字符。
/( /) 把 /( 和 /) 之间的模式保存到专门的存储空间或“存储缓冲区”中。这种方式最多可以把 9 个模式保存到单一行中。例如:
/(That/) or /(this/) 把 That 保存到 1 号存储缓冲区,把 this 保存到 2 号存储缓冲区。可以在替换中使用序列 /1 到 /9 来重新引用存储的模式。
: % s//(That/) or /(this/)//2 or /1/ 把 this or That 修改为 That or this
/< /> 在单词的开始(/<)或结尾(/>)匹配字符。单词的结束或开始由标点符号或空格决定。
注意:与 /(.../) 不同的是,这些命令不必成对使用。
~ 匹配在上次搜索中使用的任何正则表达式。(少用)
(2) 一些模式匹配例子
:% s///home//gerry///home//wcdj/g 修改文件中的路径名列表,注意,转义,使用 // 才能得到 /
:1 , 10 s//./;/g 把1到10行内的所有点号都改为分号,注意:转义
:% s/[Hh]elp/HELP/g 把单词 help(或 Help)的所有出现改为 HELP
:% s/[Hh]elp//U&/g 同上,/U把它后面的模式全部变为大写,当 & 用于替换时,它代表与搜索模式相匹配的整个文本
:g /^$/d 删除所有空行,行尾($)紧跟着行首(^)