再谈Vim substitute替换命令
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了再谈Vim substitute替换命令相关的知识,希望对你有一定的参考价值。
在Vim替换命令一文介绍过,substitute
命令的语法格式为::[range]s[ubstitute]/pattern/string/[flags]
。
[flags]
表示可选的标志位,常用的包括 g
、c
、n
、e
等。其中,标志位 g
使得 substitute
命令可以修改一行内的所有匹配,而不仅仅是第一处匹配;标志位 c
可以确认或拒绝每一处修改;标志位 n
让 Vim 不执行替换操作,而只是统计和显示本次 substitute 命令匹配的个数;标志位 e
专门用于屏蔽错误提示;标志位 &
用于指示 Vim 重用上一次 substitute 命令所用过的标志位。
一、Vim substitute命令的操作范围
为了便于理解,可以将整个文件想象成一个二维平面,字符沿着 x 轴向右增加,而文本行则随着 y 轴向下增长。缺省情况下,substitute
命令仅仅作用于当前行,而且只会修改第一处匹配。
怎么才能将替换范围扩大到由 x 与 y 轴所围的整个平面?本文接下来以将下文中出现的所有单词 going 都替换为 rolling 为例逐步进行说明。
When the going gets tough, the tough get going.
If you are going through hell, keep going.
使用 substitute
命令,最简单的方法就是为其提供待匹配的模式 pattern
以及替换字符串 string
。因此,先尝试在 Vim 命令行模式下执行命令:
:s/going/rolling
执行完上述命令后,可以发现 Vim 已经将第一处 going 替换成了 rolling,但是文中其他匹配的内容并没有发生替换。
为了使 substitute 命令作用于整个横轴,需要使用标志位 g
。
g
看似为全局 (global) 的含义,容易让人误以为 g
标志位是用于实现在整个文件范围内进行替换操作,但实际上,g
仅表示当前一整行范围。由于 Vim 直接继承自 "行编辑器 ed",对于行编辑器而言,全局的范围就是一行,这就是 g
标志位命令的由来。
继续尝试在 Vim 命令行模式下执行命令:
:s/going/rolling/g
执行完该命令后,发现所有出现在当前行的 going 都被替换成了 rolling 了,但除当前行外的文件其他位置,仍然有一些匹配未被修改。
如何才能控制 substitute
命令在整个文件的纵轴上执行呢?
答案就是使用 subsititute
命令格式中的 [range]
来指定一个执行范围。如果需要在整个文件的每一行都执行替换命令,只需要在 substitute
命令的开头加上前缀 %
,关于 range
的具体使用,推荐阅读Vim操作范围、文件范围介绍。
这次,尝试在 Vim 命令行模式下执行下述命令,发现确实把整个文件中的 going 单词替换成了新单词 rolling。
:%s/going/rolling/g
总结上述的内容就是:如果想在当前文件中查找并替换部分匹配,就必须明确地指示 substitute
命令在整个 x 轴与 y 轴上执行的具体范围,即通过标志位 g
处理横轴字符的同时,使用 range
指定处理纵轴的范围。
二、手工控制每一次替换操作
有些时候,在执行具体的替换操作前,可能需要先观察该处匹配再决定是否需要进行替换。
例如,在某个文件中,假设单词 going 一共出现了 10 次,出于具体语境需要,第 3 次出现的 going 并不应该被替换成 rolling,如果直接使用 :%s/going/rolling/g
则会把所有的 going 替换成 rolling,这显然不符合要求。
为了完成上述的操作目的,需要使用用标志位 c
来控制 substitute
命令的行为,需要执行的命令为:
:%s/going/rolling/gc
增加标志位 c
后,Vim 会在替换每处匹配结果之前都提示 "替换为 rolling ?" 供操作者手工确认,可以按 y
键确认一次修改,也可以按 n
键,跳过一次修改。无论选择哪种结果,Vim 都会执行输入的决定并移动光标到下一匹配处再次进行提示。
除了可以选 y
确认,选 n
跳过以外,还可以键入 q
退出此次替换过程,使用 a
指示 Vim 替换该处及该处后所有的匹配而无需再由人工确认,也可以使用 l
指示 Vim 替换当前处匹配后直接退出替换过程。
下表总结了针对 Vim 替换提示所给出的所有答案及用途。
答案 | 用途 |
---|---|
y |
替换此处匹配 |
n |
忽略此处匹配 |
q |
退出替换过程 |
l |
替换此处匹配后退出 (l 表示 last) |
a |
替换此处与之后所有的匹配 (a 表示 all) |
<Ctrl-e> |
向上滚动屏幕 |
<Ctrl-y> |
向下滚动屏幕 |
以上是关于再谈Vim substitute替换命令的主要内容,如果未能解决你的问题,请参考以下文章