Learn Vim 第十三章:全局命令
本文翻译自 iggredible/Learn-Vim,部分内容有增改。
到目前为止,您已经了解了如何使用点命令(.)重复上一次更改,如何使用宏(q)重复动作以及将文本存储在寄存器中(")。
在本章中,您将学习如何在全局命令中重复命令行命令。
全局命令概述
Vim的全局命令用于同时在多行上运行命令行命令。
全局命令具有以下语法:
:g/pattern/command
pattern匹配包含该模式串的所有行,类似于替代命令中的模式串。command可以是任何命令行命令。全局命令通过对与pattern匹配的每一行执行command来工作。
如果您具有以下表达式:
const one = 1;
console.log("one: ", one);
const two = 2;
console.log("two: ", two);
const three = 3;
console.log("three: ", three);
要删除所有包含”console”的行,可以运行:
:g/console/d
结果:
const one = 1;
const two = 2;
const three = 3;
全局命令在与”console”模式串匹配的所有行上执行删除命令(d)。
逆向匹配
要在不匹配的行上运行全局命令,可以运行:
:g!/{pattern}/{command}
或者
:v/{pattern}/{command}
如果运行:v/console/d,它将删除 不 包含”console”的所有行。
模式串
全局命令使用与替代命令相同的模式串系统。
要删除包含”one”或”two”的行,请运行:
:g/one\|two/d
要删除包含任何一位数字的行,请运行:
:g/\d/d
传递范围参数
您可以在g命令之前传递一个范围:
:1,5g/console/d删除第1行和第5行之间匹配字符串”console”的行。:,5g/console/d如果逗号前没有地址,则从当前行开始。:3,g/console/d如果逗号后没有地址,则在当前行结束。:3g/console/d如果只传递一个地址而不带逗号,则仅在第3行执行命令。
除了数字,您还可以将这些符号用作范围:
.表示当前行。$表示文件的最后一行。+n表示当前行之后的n行。
普通模式命令
您可以将全局命令和:normal命令行命令一起运行。
如果您有以下文字:
const one = 1
console.log("one: ", one)
const two = 2
console.log("two: ", two)
要添加”;”运行到每一行的末尾:
:g/./normal A;
:g是全局命令。/./是”非空行”的模式。它匹配至少包含1个字符的行。normal A;运行:normal命令行命令。A;是普通模式命令,用于在该行的末尾插入”;”。
执行宏
您也可以使用全局命令执行宏。如果您有以下表达式:
const one = 1
console.log("one: ", one);
const two = 2
console.log("two: ", two);
创建一个宏,以在寄存器”a”的这些行的末尾添加分号:
qa0A;<esc>q
现在运行:
:g/const/normal @a
所有带有”const”的行的末尾将带有”;”。
递归全局命令
全局命令本身是命令行命令的一种,因此您可以从技术上在全局命令中运行全局命令。
:g/console/g/two/d
首先,g将查找包含模式”console”的行。然后,第二个”g”将从那三个匹配项中查找包含模式”two”的行。最后,它将删除该匹配项。
您也可以将g与v结合使用以找到正负模式:
:g/console/v/two/d
它将查找 不 包含”two”的行。
更改定界符
您可以像替代命令一样更改全局命令的定界符。规则是相同的:您可以使用任何单字节字符,但字母,数字,", |, 和 \除外。
要删除包含”console”的行:
:g@console@d
如果在全局命令中使用替代命令,则可以有两个不同的定界符:
g@one@s+const+let+g
默认命令
如果在全局命令中未指定任何命令行命令,全局命令将使用打印(:p)命令来打印当前行的文本。
:g/console
它将在屏幕底部打印所有包含”console”的行。
顺便说一句,这是一个有趣的事实。因为全局命令使用的默认命令是p,所以这使g语法为:
:g/re/p
g= 全局命令re= 正则表达式模式p= 打印命令
这三个元素连起来拼写为 “grep”,与命令行中的grep 相同。g/re/p命令最初来自Ed编辑器。
反转整个缓冲区
要翻转整个文件,请运行:
:g/^/m 0
如果只需要反转几行,请将其传递一个范围。要将第5行到第10行之间的行反转,请运行:
:5,10g/^/m 0
汇总所有待办事项
要将所有TODO复制到文件末尾以便于自省,请运行:
:g/TODO/t $
如果不想复制,而是将所有的 TODO 移动到末尾,可以使用移动命令 m:
:g/TODO/m $
黑洞删除
为了避免删除的行存储到寄存器中,您可以使用黑洞寄存器("_):
:g/console/d _
将多条空行减少为一条空行
:g/^$/,/./-1j
/^$/表示一个空行。/./表示一个非空行。-1意思是向上偏移1行。j是联接命令。
如果想要将多个空行全部删去:
:g/^$/,/./j
高级排序
如果需要排序数组中的元素,而不是数组本身,可以运行以下命令:
:g/\[/+1,/\]/-1sort
/\[/+1匹配左方括号”[“的下面1行。/\]/-1匹配右方括号”]”的上面1行。sort是命令行命令:排序。
聪明地学习全局命令
全局命令针对所有匹配的行执行命令行命令。有了它,您只需要运行一次命令,Vim就会为您完成其余的工作。要精通全局命令,需要做两件事:良好的命令行命令词汇表和正则表达式知识。
每当需要在多个位置应用命令时,请暂停并查看是否可以使用g命令。寻找最适合工作的命令,并编写一个模式串以同时定位多个目标。