vim之强大的global

vim global :global 命令是 Vim 中一个更强大的命令 (之一)。它允许你找到一个匹配点并且在那里执行一个命令。它的一般形式是:

:[range]g/{pattern}/{command}

在每一匹配行上执行命令command. 这个命令只能是冒号命令, 普通模式命令不能在这里使用。如果需要,可以使用:normal命令。
如果要查看可以使用的命令,可以help ex-cmd-index。 如果要查看详细解释, 查看help 10.4help multi-repeat
vglobal相当于global!, 两者可以组合使用, 如:g/found/v/notfound/{cmd}
利用global我们可以把我们之前学的很多东西都串连起来,以完全一些非常奇妙的动作。
所以下面我们通过示例来学习global的用法。
示例
示例一 用法: 显示匹配行上下共3行, 第二写法能更清晰的看到上下3行
:g/patttern/z#.3 :g/pattern/z#.3|echo "========"

vim之强大的global
文章图片

关于z的用法,可以输入help :z, 如下所示
:{range}z[+-^.=]{count}
显示包围 {range} 指定行的若干行文本,如果没有 {range},显示当前行上下的文本。如果有 {count},它指定 你能看到的行数。否则,如果只有一个窗口,使用 'scroll' 选项值的两倍。再不然,使用当前的窗口大小减 3。
如果提供了 {count},'window' 选项会被设为该值。
:z 可以单独使用,也可以后跟数个标点符号中的一个。他们有如下的效果:
标记 首行 末行 新光标行
+ 当前行 向前 1 屏 向前 1 屏
- 向后 1 屏 当前行 当前行
^ 向后 2 屏 向后 1 屏 向后 1 屏
. 向后 1/2 屏 向前 1/2 屏 向前 1/2 屏
= 向后 1/2 屏 向前 1/2 屏 当前行
不指定任何标记相当于指定 "+"。如果标记是 "=",当前行会 被连字符组成的两行包围。
:{range}z#[+-^.=]{count}
和 ":z" 类似,但显示行号。
示例二 用法: 删除所有匹配行 或 所有不匹配行
:g/pattern/d :g!/pattern/d :v/pattern/d

g!v是等价的。
这个例子的一个用法就是删除所有空行
:g/^\s*$/d

示例三 用法: 在所有行之间加上空行
:g/^/pu \"\n\"

关于pu的用法,可以输入:help :put
:[line]pu[t] [x]
放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之后。它总是 |linewise| 行动作,因而这个命令可以用来把抽出的块放置在新行上。寄存器也可以是 '=',跟随一个可选的表达式。表达式继续到该命令结束为止。你需要在 '|' 和 '"' 字符前加上反斜杠不让它们终止你的命令行。例如: :put ='path' . \",/test\" ; 如果 '=' 之后没有表达式,Vim 使用前一个表达式。用 ":dis =" 你可以看到它。|
示例四 用法: 将所有匹配行附加到文件尾
:g/pattern/t$

关于t的用法,可以输入help :t。 它的用法同copy
command usage
:[line]pu[t]! [x] 放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之前。
:[range]co[py] {address} 把 [range] 指定的行复制到 {address} 给出的行之下。
:[range]m[ove] {address} 把 [range] 指定的行移动到 {address} 给出的行之下。
示例五 用法: 将所有匹配行移动到文件尾
:g/pattern/m$

示例六 用法: 复制所有匹配行到寄存器'a'
qaq:g/pattern/y A

这里的命令分成两部分:
qaq : 清空寄存器'a'的内容
:g/pattern/y A : y A是一个Ex命令,可以通过help :yank来了解具体作用,它把所有的匹配行复制(附加)到寄存器'a'中。
:[range]y[ank] [x]
抽出 [range] 所指定的行 [到寄存器 x]。仅当包含|+clipboard| 特性时才可以抽出到 "* 或 "+ 寄存器。
:[range]y[ank] [x] {count}
从 [range] 的最后一行开始 (缺省: 当前行|cmdline-ranges|) 抽出 {count} 行 [到寄存器 x]。
示例七 用法: 从本行到行尾将行首的数字都加1
:.,$g/^\d\+/exe "normal! \"

.,$ : 从本行到行尾
^\d\+ : 行首是数字
exe "normal! \ : 执行normal命令, 相当于在匹配项上按键, 可以将当前数字加1
关于特殊字符,可以输入help expr-quote来查看
s
"string" 字符串常数 expr-quote
注意 使用的是双引号。
字符串常数接受以下特殊字符:
字符 含义
\... 三位八进制数 (例如,"\316")
\.. 两位八进制数 (必须后跟非数字)
\. 一位八进制数 (必须后跟非数字)
\x.. 两位十六进制数指定的字节 (例如,"\x1f")
\x. 一位十六进制数指定的字节 (必须后跟非十六进制数字)
\X.. 等同于 \x..
\X. 等同于 \x.
\u.... 四位十六进制指定的字符。根据 'encoding' 的当前值决定的编码进行存贮 (例如,"\u02a4")
\U.... 等同于 \u 但接受多达 8 位十六进制数。
\b 退格
\e escape
\f 换页
\n 换行
\r 回车
\t 制表
\\ 反斜杠
\" 双引号
\ "xxx" 命名的特殊字符,例如 "\" 代表 CTRL-W。用于映射,0x80 字节被转义。
双引号必须转义: ""
不要用 来得到 utf-8 字符,用上面提到的 \uxxxxx
注意 "\xff" 保存为字节 255,在某些编码中它是不合法的。使用 "\u00ff" 可以按照 'encoding' 的当前值保存字符 255。
注意 "\000" 和 "\x00" 强制字符串结束。
关于递增和递减, 可以用help CTRL-A来查看
递 增 与 递 减 ~
CTRL-A
把当前光标之上或之后的数值或者字母加上 [count]。
{Visual}CTRL-A
给高亮文本内的数值或者字母加上 [count]。
{Visual}g CTRL-A
给高亮文本内的数值或者字母加上 [count]。如果高亮超过一 行,每行会加上额外的 [count] (即生成 [count] 为增量的 递增数列)。
例如,假定有如下数字的列表:
1. 1. 1. 1.

移动至第二个 "1.",可视地选择后三行,按 g CTRL-A 会生
生成:
1. 2. 3. 4.

CTRL-X
把当前光标之上或之后的数值或者字母减去 [count]。
{Visual}CTRL-X
给高亮文本内的数值或者字母减去 [count]。
MS-Windows 上,此键被映射到剪切可视文本 |dos-standard-mappings|。要屏蔽该映射,可用: silent! vunmap
{Visual}g CTRL-X
给高亮文本内的数值或者字母减去 [count]。如果高亮超过一 行,每行会减去额外的 [count] (即生成 [count] 为增量的 递减数列)。
CTRL-A 和 CTRL-X 命令可用于:
  • 带符号或无符号十进制数
  • 无符号二进制、八进制和十六进制数
  • 字母
示例八 用途: 在所有包含DEBUG的行用/ ... /变成注释
" using :normal g/^\s*DEBUG/exe "norm! I/* \A */\" " using :substituting g/^\s*DEBUG/s!.*!/* & */!

这里&用来表示前面的整个匹配项
示例九 用途: 显示匹配行的上一行
:g/pattern/?^\w?p"if only name is interesting :g/pattern/ka|?^\w?p|'ap"if name and the lookup-line is interesting :g/pattern/?^\w?|+,/^[^ ]/-1p"if entire record is interesting

关于?^\w?, 两个?之间的就是要匹配的模式, ^\w表示开头不为空的行,p表示put`在前面已经讲过
?可以查看help cmdline-range.
符号 行号
{number} 行号
. 当前行
$ 文件的最后一行
% 相当于 1,$ (整个文件)
't 标记 t 的位置 (小写)
'T 标记 T 的位置 (大写);如果标记存在于另一个文件中,则不能在范围里应用。
/{pattern}[/] 下一个 匹配 {pattern} 的行
?{pattern}[?] 前一个 匹配 {pattern} 的行
/ 下一个 与前次搜索模式匹配的行
? 前一个 与前次搜索模式匹配的行
\& 下一个 与前次替代模式匹配的行
关于ka, 可以查看help :k
:[range]ma[rk] {a-zA-Z'}
把位置标记 {a-zA-Z'} 设在 [range] 的最后一行,第 0 列。缺省的 [range] 是当前行。
:[range]k{a-zA-Z'}
和 :mark 相同, 但是标记名之前的空格可以省略。
示例十 用途: 反转文件行
:g/^/m0

前面已经讲过m表示move
示例十一 用途: 在以某关键字开关的行尾加上某字符
:g/^pattern/s/$/mytext

示例十二 用途: 删除匹配行
:g/pattern/d _

默认情况下, 所有删除行会被复制到unnamed register,当文件很多时,性能会被影响到,所以这里把内容复制到黑洞register, 相当于NOP, 这样可以提高性能
一些常见命令:
:2,8co15"copy lines 2 through 8 after line 15 :4,15t$"copy lines 4 through 15 to end of document (t == co) :-t$"copy previous line to end of document :m0"move current line to line 0 (i.e. the top of the document) :.,+3m$-1 "current line through current+3 are moved to the lastLine-1 (i.e. next to last)

示例十三 用途: 在一段范围里替换字符
:'a,'bg/pattern/s/pattern2/string/gi

示例十四 用途: 在匹配行,执行寄存器q里的动作
:g/pattern/normal @q

示例十五 用途: 删除连续的重复行
:g/^\(.*\)\(\r\?\n\1\)\+$/d :%!uniq

\r\?\n可以用于匹配换行, \r是可选的
g用来搜索多行匹配时,它只将command作用于匹配的第一行, 而不是整个的匹配
示例十六 用途: 合并多个连接的空行为一行
:v/./,/./-j

  • jjoin的综合,它会把多行连接成一行。
  • ,/./-是一个范围, 完整形式是.,/./-1, 表示当前行到非空行的上一行
J
连接 [count] 行,但至少包含两行。删除缩进,插入不多于两个的空格 (见下)。在缓冲区末行此操作会失败。[count] 如果过多,会自行缩减至余下可用的行。
{Visual}J
连接高亮行,但至少包含两行。删除缩进,插入不多于两个的空格 (见下)。
gJ
连接 [count] 行,但至少包含两行。不插入或删除任何空格。
{Visual}gJ
连接高亮行,但至少包含两行。不插入或删除任何空格。
[range]j[oin][!] [flags]
连接 [range] 范围的行。和 "J" 相同,但如有 [!] 时,连接不插入或删除任何空格。如果 [range] 包括相同的开始和结束行,该命令不做任何事。缺省行为是连接当前行与下一行。[flags] 部分可参见 |ex-flags|。
:[range]j[oin][!] {count} [flags]
连接 [range] 开始的 {count} 行 (缺省: 当前行 |cmdline-ranges|)。和 "J" 相同,但如有 [!] 时,连接不插入或删除任何空格。[flags] 部分可参见 |ex-flags|。
示例十七 用途: 对关键字包围的端口声明按字母排序
:g/\/\/define begin/+1,/\/\/define end/-1 sort:g/{/ .+1,/}/-1 sort

vim之强大的global
文章图片

示例十八 用途: 在以"module"开头的行下面都增加分隔线
:g/^module/t.|s/./\//g

vim之强大的global
文章图片

示例十九 用途: 将某字符行下的第二行打印到某个已存在文件
:g/^Chapter/+2w >> context

vim之强大的global
文章图片

【vim之强大的global】引用:
https://vim.fandom.com/wiki/P...
https://wsdjeg.spacevim.org/v...

    推荐阅读