%s
Vim 的替换命令基于 substitute (替换) 命令,其基本语法为:

:[range]s/{pattern}/{string}/[flags]
我们来分解一下这个语法:
- : 进入命令行模式。
[range]: 指定替换操作的范围。- : 表示整个文件,这是最常用的范围。
10,20: 表示从第 10 行到第 20 行。- : 表示从当前行到文件末尾。
1,$: 同样表示从第 1 行到最后一行,等同于 。- 如果不指定范围,默认只对当前光标所在行进行替换。
s:substitute命令的缩写。{pattern}: 你想要查找的字符串或正则表达式。{string}: 你想要替换成的字符串。[flags]: 控制替换行为的标志。g(global): 全局替换,如果一行中有多个匹配项,全部替换,如果没有g,则一行中只替换第一个匹配项。c(confirm): 确认替换,每次替换前都会提示你是否确认。n(number): 显示匹配的数量,但不实际进行替换,这对于检查有多少个匹配项很有用。i(ignore case): 忽略大小写进行匹配。I(no ignore case): 不忽略大小写(即使set ignorecase设置了,也强制区分大小写)。- 标志可以组合使用,
gc表示“全局且每次确认”。
常用替换命令示例
全局替换
场景:将文件中所有的 "old" 替换为 "new"。
:%s/old/new/g
- 整个文件
s: 替换/old/: 查找 "old"/new/: 替换为 "new"/g: 全局替换
行内替换第一个匹配项
场景:在当前行,将第一个 "apple" 替换为 "orange"。
:s/apple/orange/
- 没有指定范围,所以默认是当前行。
- 没有
g标志,所以只替换当前行的第一个 "apple"。
特定行范围替换
场景:将第 5 行到第 10 行的所有 "error" 替换为 "warning"。

:5,10s/error/warning/g
交互式(确认式)替换
场景:你想将所有的 "foo" 替换为 "bar",但又不确定是否所有 "foo" 都要替换,希望在替换前确认一下。
:%s/foo/bar/gc
执行后,Vim 会跳到第一个匹配项,并在底部命令行显示:
replace with bar (y/n/a/q/l/^E/^Y)?
y(yes): 替换当前这个。n(no): 不替换当前这个,跳到下一个。a(all): 替换所有剩余的匹配项,不再询问。q(quit): 退出替换模式。l(last): 替换当前这个,然后立即退出替换模式。^E/^Y: 向上/向下滚动屏幕(用于查看上下文)。
忽略大小写替换
场景:将所有 "Linux"(大小写任意)替换为 "GNU/Linux"。
:%s/Linux/GNU/Linux/gi
i标志表示忽略大小写。
高级技巧
使用特殊分隔符
如果你的查找或替换字符串中包含斜杠 ,为了避免转义,可以使用其他字符作为分隔符,、、 等。
场景:将路径 /usr/local/bin 替换为 /opt/bin。
# 使用 # 作为分隔符 :%s#/usr/local/bin#/opt/bin#g # 使用 | 作为分隔符 :%s|/usr/local/bin|/opt/bin|g
使用正则表达式
Vim 的替换命令支持强大的正则表达式。
场景:删除行尾的所有注释(假设注释以 开头)。
:%s|//.*$||g
- 匹配 字符本身。
- 匹配任意字符()零次或多次()。
- 匹配行尾。
- 整个 就匹配了从 开始到行尾的所有内容。
- 替换为空字符串 ,相当于删除。
场景:将形如 key = value 的字符串替换为 value = key。
:%s/\(\w+\)\s*=\s*\(\w+\)/\2 = \1/g
\(\w+\): 匹配一个或多个单词字符(字母、数字、下划线),并将其捕获为第一个分组\1。\s*: 匹配零个或多个空白字符(空格、制表符)。- 匹配等号。
\(\w+\): 再次匹配一个或多个单词字符,并将其捕获为第二个分组\2。- 替换部分
\2 = \1表示使用第二个分组的内容,然后是 " = ",最后是第一个分组的内容。
使用寄存器内容进行替换
场景:你想将所有的 "foo" 替换为系统剪贴板中的内容。
-
复制系统剪贴板的内容到 Vim 的一个寄存器,
"a,假设剪贴板内容是 "bar baz"。 在普通模式下输入:"ayy(复制当前行到寄存器 a) 或者在插入模式下用Ctrl+R a粘贴。 -
然后执行替换命令:
:%s/foo/"a/g
"a表示使用寄存器a中的内容作为替换字符串。
确认替换数量而不实际替换
场景:你想知道文件中有多少个 "TODO"。
:%s/TODO//n
n标志会告诉你匹配的数量,pattern not found: TODO(如果没有找到) 或者2 matches on 2 lines(如果找到了2个匹配项)
总结表格
| 命令 | 作用 | 解释 |
|---|---|---|
%s/old/new/g |
全局替换 | 将文件中所有的 "old" 替换为 "new"。 |
s/old/new/ |
行内替换第一个 | 只替换当前行的第一个 "old"。 |
5,10s/old/new/g |
范围替换 | 替换第 5 到 10 行的所有 "old"。 |
%s/old/new/gc |
交互式替换 | 替换所有 "old",但每次都让你确认。 |
%s/old/new/gi |
忽略大小写替换 | 不区分大小写地替换所有 "old"。 |
%s|/path/to/old|/path/to/new|g |
使用不同分隔符 | 当路径中包含 时,用 \| 代替。 |
%s/.*// |
删除整行内容 | 匹配任意字符到行尾,并替换为空。 |
%s/\(\w\+\)/\1/g |
使用反向引用 | 保留匹配到的内容(这里是单词)。 |
安全提示
- 先读后写:在执行大规模替换前,特别是使用正则表达式时,先用
n命令确认匹配项的数量。:%s/pattern//n
- 备份文件:对于重要的文件,先创建一个备份再操作。
:%s/old/new/g > backupfile.txt
或者使用 Vim 的自动备份功能(
set backup)。 - 从当前行开始测试:可以先不指定范围 ,只用
s/.../.../g在当前行测试,确认无误后再对整个文件操作。
希望这份详细的指南能帮助你熟练掌握 Vim 的替换命令!
