第13章 全局命令
全局命令
到目前为止,您已经了解了如何使用点命令(.
)重复上一次更改,如何使用宏(q
)重播动作以及将文本存储在寄存器中("
)。
在本章中,您将学习如何在全局命令中重复命令行命令。运行一次,应用于任何地方(在缓冲区中)。
全局命令概述
Vim的全局命令用于同时在多行上运行命令行命令。
顺便说一句,您之前可能已经听说过“ Ex命令”一词。在本书中,我将它们称为命令行命令,但Ex命令和命令行命令是相同的。它们是以冒号(:
)开头的命令。在上一章中,您了解了替代命令。这是一个Ex命令的示例。它们之所以称为Ex,是因为它们最初来自Ex文本编辑器。在本书中,我将继续将它们称为命令行命令。有关Ex命令的完整列表,请查看:h ex-cmd-index
。
全局命令具有以下语法:
pattern
匹配包含该模式的所有行,类似于替代命令中的模式。command
可以是任何命令行命令。全局命令通过对与pattern
匹配的每一行执行command
来工作。
如果您具有以下表达式:
要删除所有包含“控制台”的行,可以运行:
结果:
全局命令在与“控制台”模式匹配的所有行上执行删除命令(d
)。
运行g
命令时,Vim对文件进行两次扫描。在第一次运行时,它将扫描每行并标记与/console/
模式匹配的行。一旦所有匹配的行都被标记,它将进行第二次运行,并在标记的行上执行d命令。
如果要删除所有包含“const”的行,请运行:
结果:
逆向比赛
要在不匹配的行上运行全局命令,可以运行:
要么
如果运行:v/console/d
,它将删除不包含“console”的所有行。
模式
全局命令使用与替代命令相同的模式系统,因此本节将作为更新。随意跳到下一部分或继续阅读!
如果您具有以下表达式:
要删除包含“one”或“two”的行,请运行:
要删除包含任何一位数字的行,请运行以下任一命令:
要么
如果您有表达式:
要匹配包含三到六个零的行,请运行:
传递范围
您可以在g
命令之前传递一个范围。您可以通过以下几种方法来做到这一点:
:1,5/g/console/d
在第1行和第5行之间匹配字符串"console"并将其删除。:,5/g/console/d
如果逗号前没有地址,则从当前行开始。它在当前行和第5行之间寻找字符串"console"并将其删除。:3,/g/console/d
如果逗号后没有地址,则在当前行结束。它在第3行和当前行之间寻找字符串"console"并将其删除。:3g/console/d
如果只传递一个地址而不带逗号,则仅在第3行执行命令。在第3行查找,如果字符串为"console",则将其删除。
除了数字,您还可以将这些符号用作范围:
.
表示当前行。范围.,3
表示当前行和第3行之间。$
表示文件的最后一行。3,$
范围表示在第3行和最后一行之间。+n
表示当前行之后的n行。您可以将其与.
结合使用,也可以不结合使用。3,+1
或3,.+1
表示在第3行和当前行之后的行之间。
如果您不给它任何范围,默认情况下它将影响整个文件。这实际上不是常态。如果您不传递任何范围,Vim的大多数命令行命令仅在当前行上运行。两个值得注意的例外是全局(:g
)和save(:w
)命令。
普通命令
您可以将全局命令和:normal
命令行命令一起运行。
如果您有以下文字:
要添加";"运行到每一行的末尾:
让我们分解一下:
:g
是全局命令。/./
是“非空行”的模式。回想一下正则表达式中的点(.
)表示任何字符。它将行与至少一个字符匹配,因此将行与“const”和“console”匹配。它不匹配空行。normal A;
运行:normal
命令行命令。A;
是普通模式命令,用于在该行的末尾插入";"。
执行宏
您也可以使用全局命令执行宏。宏只是普通模式下的操作,因此可以使用:normal
来执行宏。如果您有以下表达式:
请注意,带有"const"的行没有分号。让我们创建一个宏,以在寄存器"a"的这些行的末尾添加逗号:
如果您需要复习,请查看有关宏的章节。现在运行:
现在,所有带有"const"的行都将带有";"在末尾。
递归全局命令
全局命令本身是命令行命令的一种,因此您可以从技术上在全局命令中运行全局命令。
给定表达式:
如果您运行:
首先,“g”将查找包含模式“console”的行,并找到3个匹配项。然后,第二个“g”将从那三个匹配项中查找包含模式“two”的行。最后,它将删除该匹配项。
您也可以将“g”与“v”结合使用以找到正负模式。例如:
而不是查找包含模式"two"的行,它将查找不包含"two"的行。
更改定界符
您可以像替代命令一样更改全局命令的定界符。规则是相同的:您可以使用任何单字节字符,但字母,数字,"
, |
, 和 \
除外。
要删除包含"console"的行:
如果在全局命令中使用替代命令,则可以有两个不同的定界符:
此处,全局命令将查找包含“one”的所有行。 替换命令将从这些匹配项中将字符串"const"替换为"let"。
默认命令
如果在全局命令中未指定任何命令行命令,会发生什么?
全局命令将使用打印(:p
)命令来打印当前行的文本。如果您运行:
它将在屏幕底部打印所有包含"console"的行。
顺便说一下,这是一个有趣的事实。因为全局命令使用的默认命令是p
,所以这使g
语法为:
g
= 全局命令re
= 正则表达式模式p
= 打印命令
它拼写"grep",与命令行中的grep
相同。但这 不 是巧合。 g/re/p
命令最初来自第一行文本编辑器之一的Ed编辑器。 grep
命令的名称来自Ed。
您的计算机可能仍具有Ed编辑器。从终端运行ed
(提示:要退出,请键入q
)。
更多示例
反转整个缓冲区
要撤消整个文件,请运行:
^
是“行的开始”的模式。使用^
匹配所有行,包括空行。
如果只需要反转几行,请将其传递一个范围。要将第五行到第十行之间的行反转,请运行:
要了解有关move命令的更多信息,请查看:h :move
。
汇总所有待办事项
当我编码时,有时我会想到一个随机的绝妙主意。不想失去专注,我通常将它们写在我正在编辑的文件中,例如:
跟踪所有已创建的TODO可能很困难。 Vim有一个:t
(copy)方法来将所有匹配项复制到一个地址。要了解有关复制方法的更多信息,请查看:h :copy
。
要将所有TODO复制到文件末尾以便于自省,请运行:
结果:
现在,我可以查看我创建的所有TODO,找到时间来完成它们或将它们委托给其他人,然后继续执行下一个任务。
另一种选择是使用m
:
结果:
一旦决定要删除列表,就可以删除它。
黑洞删除
从寄存器一章回想一下,已删除的文本存储在已编号的寄存器中(允许它们足够大)。每当运行:g/console/d
时,Vim都会将删除的行存储在编号寄存器中。如果删除许多行,则可以快速填充所有编号的寄存器。为了避免这种情况,您始终可以使用黑洞寄存器(“ _
)不将删除的行存储到寄存器中。
通过在d
之后传递_
,Vim不会将删除的行保存到任何寄存器中。
将多条空行减少为一条空行
如果您的文件带有多个空行,如下所示:
您可以快速将每条长长的空行减少为一条空行。运行:
结果:
让我们分解一下:
:g
是全局命令/^$/
是空行的模式。回想一下,^
表示行的开始,$
表示行的结束。^ $
匹配一个空行(一个零字符长的行)。,/./-1
是j
命令的范围。由于您没有传递起始范围的值,因此它从当前行开始。您之前已经了解到/./
是非空行的模式。,/./
是从当前行到下一个非空行的范围。全局命令的范围/^$/
会将您带到console.log("one: ", one);
下面的第一行。这是当前行。/./
匹配第一条非空行,即const two = 2;
行。最后,-1
将其偏移一行。第一次匹配的有效范围是console.log("one: ", one);
下方的空行和const two = 2;
上方的空行。j
是连接命令:j
。您可以加入所有作为其范围的行。例如,:1,5j
连接第一到第五行。请注意,您正在
j
命令之前传递范围(,/./-1
)。仅仅因为您在全局命令中使用了命令行命令,并不意味着您不能给它一个范围。在这段代码中,您将传递给j
命令自己的范围来执行。您可以在执行全局命令时将范围传递给任何命令。
顺便说一句,如果您想将多条空行减少为无行,而不是将,/./-1
用作j
命令的范围,只需使用,/./
作为范围:
或更简单:
您的文字现在减少为:
高级排序
Vim有一个:sort
命令来对一个范围内的行进行排序。例如:
您可以通过运行:sort
对它们进行排序。如果给它一个范围,它将只对该范围内的行进行排序。例如,:3,5sort
仅在第三和第五行之间排序。
如果您具有以下表达式:
如果需要排序数组中的元素,而不是数组本身,可以运行以下命令:
结果:
这很棒!但是命令看起来很复杂。让我们分解一下。该命令包含三个主要部分:全局命令模式,排序命令范围和排序命令。
:g/\[/
是全局命令模式。
:g
是全局命令。/\[/
是全局命令使用的模式。\[
查找文字"["字符串。
+1,/\]/-1
是排序命令的范围。
范围可以有开始和结束地址。在这种情况下,
+1
是起始地址,/\]/-1
是结束地址。+1
表示当前行之后的行,这是与全局命令中的模式“ [”匹配的行。 “ +1”将当前行偏移一行。因此,在第一个匹配项中,范围实际上是在const arrayB = [
文本之后的一行。/\]/-1
是结束地址。\]
代表一个文字的右方括号“]”。-1
将其偏移一行。结束地址是"]"上方的行。
sort
是sort命令行命令。它对给定范围内的所有内容进行排序。 "["到上方的行"]"之后的所有内容均已排序。
如果您仍然对该命令感到困惑,请不要担心。我花了很长时间才掌握它。稍事休息,离开屏幕,然后重新思考。
聪明地学习全局命令
全局命令针对所有匹配的行执行命令行命令。有了它,您只需要运行一次命令,Vim就会为您完成其余的工作。要精通全局命令,需要做两件事:良好的命令行命令词汇表和正则表达式知识。随着您花费更多的时间使用Vim,您自然会学到更多的命令行命令。正则表达式知识将需要更积极的方法。但是,一旦您对正则表达式感到满意,您将领先于很多。
这里的一些例子很复杂。不要被吓到。真是花时间了解它们。学习阅读模式。确保您知道每个命令中的每个字母代表什么。不要放弃。
每当需要在多个位置应用命令时,请暂停并查看是否可以使用g
命令。寻找最适合工作的命令,并编写一个模式以同时定位多个目标。然后重复执行此操作,直到您无需考虑即可进行操作。下次,看看是否有更快,更有效的方法。
既然您已经知道全局命令的功能强大,那么让我们学习如何使用外部命令来增加工具库。
Last updated
Was this helpful?