当前位置:首页>Linux>Linux vi/vim 重复编辑操作

Linux vi/vim 重复编辑操作

  • 2026-10-21 13:29:26
Linux vi/vim 重复编辑操作

编辑工作往往不是杂乱无章的。同一个修改动作常常会被重复多次。先跟随笔者打开 vim,然后一步步完成下面的操作。可能不会一次就成功,那就多试几次吧。

q 相当于其它编辑器中的宏录制功能。

在普通模式下操作序列如下:

qa 操作序列 q
  • qa:开始录制,并将操作记录在寄存器 a。
  • 操作序列:各种编辑操作。
  • q: 再次按下后停止录制。

录制完后:

  • @a:会 replay 被录制的宏。
  • @@:是一个快捷键用来 replay 最新录制的宏。

示例演示:

"打开vim, 在第一行输入数字 1"按下 <ESC> 键后,再键入如下命令:qaYp<C-a>q
  • qa 开始录制,注意观察状态栏的变化:recording @a
  • Yp 复制并输出到下一行.
  • <C-a> 按下 ctrl + a 增加 1.
  • q 停止录制.

接下来在普通模式下重放录制的操作:

"现在光标应该在第 2 行@a  "在 2 下面输出 3
@@  "在 3 下面输出 4
" 重复执行 100 次100@@  "创建新的100行,并把数据增加到 104.

上面的例子可以帮你建立起 q 宏录制的基本概念。

1. 单次重复

:help single-repeat
.                       重复上次改变,有计数前缀的重复 [count] 次。                        如果 'cpoptions' 包括 'y' 标志,也可以用来重复一个抽出                        (yank) 操作。不能重复命令行命令。

简单的改变操作可以用 . 重复。如果没有数字前缀,使用上次的改变的重复次数。如果输入一个重复次数,就用它取代上次的计数。

2. 多次重复

:help multi-repeat
:[range]g[lobal]/{pattern}/[cmd]                        在 [range] 界定的匹配模式 {pattern} 的文本行上执行                        Ex 命令 [cmd] (缺省是 ":p")。:[range]g[lobal]!/{pattern}/[cmd]                        在 [range] 界定的 不 匹配模式 {pattern} 的文本行上执                        行 Ex 命令 [cmd] (缺省是 ":p")。:[range]v[global]/{pattern}/[cmd]                        同 :g!。

示例:

:g/^Obsolete/d _

:d 之后使用下划线可以避免破坏寄存器或剪贴板。速度也更快。

除了用 / 来包围 {pattern} 外,你可以用任何其它单字节字符,但不包括字母、\、"、| 或 !。这对你想在搜索模式或者替代字符串里包含 / 很有用。比如可以使用 $ 符合来包围 {pattern}。

global 命令先扫描 [range] 界定的行,然后对每个匹配的行进行标记 (对于一个跨行的匹配,则只针对开始的一行)。第二次扫描对每个标记的行,就像光标在那行那样,执行指定的 [cmd] 命令。:v 和 :g! 命令针对未标记的行进行。如果一行被删除,其标记也自动消失。

缺省的 [range] 是整个缓冲区 (1,$)。用 CTRL-C 中断该命令。如果某行的执行给出错误,该行的执行被中断,但 global 命令仍从下一个被标记或未被标记的行继续。

3. 重复组合操作

:help complex-repeat  ":help q
q{0-9a-zA-Z"}           在寄存器 {0-9a-zA-Z"} 里记录键入的字符 (大写名字的寄存                        器表示附加键入的内容)。'q' 命令不能在执行寄存器时使                        用。同样,在映射和  :normal  里也不能。                        注意: 如果用作记录的寄存器用于 y 和 p,其结果多数不如                        你的预想,因为 p 会粘贴记录的宏,而 y 会覆盖记录的宏。                        注意: 记录在你键入时发生,寄存器的重放就像按键来自映射                        一样。这种区别体现在某些地方,比如只有在命令输入时才会                        进行撤销的同步。q                       停止记录。(注意 实现细节: 停止记录的 'q' 不会被保存在                        寄存器里,除非它是映射的结果)@{0-9a-z".=*+}          执行寄存器 {0-9a-z".=*+} 的内容 [count] 次。注意 不能                        用寄存器 '%' (当前文件名) 和 '#' (轮换文件名)。                        寄存器的执行方式与映射类同,也就是说,'wildchar' 和                        'wildcharm' 的差异适用此处,而撤销的同步可能有所不同。                        "@=" 则会提示你输入一个表达式。这个表达式的结果会被执                        行。                        参见  @: 。@@                      执行上次执行的 @{0-9a-z":*} [count] 次。:[addr]@{0-9a-z".=*+}   把寄存器 {0-9a-z".=*+} 里的内容看成一个 Ex 命令执行。                        首先,把光标放在 [addr] 行 (缺省是当前行) 上。如果                        'cpoptions' 设定了 'e' 标志位而寄存器的内容最后一行没                        有 <CR>,会自动加上。                        ":@=" 使用最近使用的表达式。表达式执行的结果被当作 Ex                        命令执行。                        这些命令里,不识别映射。                        面向行的寄存器中的一行行首如果出现  line-continuation                        字符 (\),此行会和前行合并。这可用于抽取和执行 Vim 脚                        本片段。                        将来: 会对地址范围里每一行执行寄存器的命令。:[addr]*{0-9a-z".=+}                                     :star-compatible                        'cpoptions' 设置 '*' 标志位  cpo-star  时,":*" 命令和                        ":@" 相同。如果用 'nocompatible',这 并 非缺省。                        'cpoptions' 没有 '*" 标志位时,":*" 相当于 ":'<,'>",                        选择可视区域  :star 。:[addr]@:               先把光标放在 [addr] 行 (缺省是当前行) 上,然后重复上次                        的命令行。:[addr]@:[addr]@@               先把光标放在 [addr] 行 (缺省是当前行) 上,然后重复上次                        的 :@{register}。

最新文章

随机文章