菜鸟科技网

Linux vim替换命令如何高效使用?

%s

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

Linux vim替换命令如何高效使用?-图1
(图片来源网络,侵删)
:[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"。

Linux vim替换命令如何高效使用?-图2
(图片来源网络,侵删)
: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" 替换为系统剪贴板中的内容。

  1. 复制系统剪贴板的内容到 Vim 的一个寄存器,"a,假设剪贴板内容是 "bar baz"。 在普通模式下输入: "ayy (复制当前行到寄存器 a) 或者在插入模式下用 Ctrl+R a 粘贴。

  2. 然后执行替换命令:

    :%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 的替换命令!

分享:
扫描分享到社交APP
上一篇
下一篇