探索 Vim 全局命令
概述
常用命令列表
持续学习的技巧
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
关注@learnvim获取更多 Vim 使用技巧!
Vim 的全局命令(:h :global)可以用来在缓冲区中运行Ex 命令,从而实现即时编辑。掌握全局命令的使用方法可以节省大量重复性工作的时间。
如果你使用 Vim 作为文本编辑器,或者你只是在了解 Vim,本文将向你展示如何使用全局命令。
我在 2019 年写了一篇关于全局命令的文章。从那时到现在,我学到了很多新东西(即使现在,我认为我也只是触及了该命令真正力量的皮毛)。
概述
这是基本概述g。如果您已经了解,可以跳过这部分。
基本语法
根据说明:h :global,语法如下所示:
:[range]global/{pattern}/{command}
让我们逐一分析。在本节中,我将使用命令d进行演示(稍后会介绍更多命令)。更多信息,请查看……:h :delete
test.js本文后续内容也将用到它,您可以跟着一起编写代码:
const one = 1;
console.log("one: ", one);
const two = "two";
console.log("two: ", two);
const three = {num: 3};
console.log("three: ", three);
要删除所有包含“.”的行"console",我们执行以下操作:
:g/console/d
它是如何运作的?
- 首先,
g扫描指定范围。如果没有指定范围,则默认扫描整个缓冲区((1,$))。在本例中,它找到了 3 个匹配项:所有包含“console”的行。 - 其次,
d对每一行匹配项执行操作。
所以,如果您想删除所有包含等号 ( =) 的行,您可以这样做:
:g/=/d
反向匹配
要使不匹配的行而不是匹配的行生效,:g/pattern/{command}您可以执行以下操作之一:
:g!/{pattern}/{command}:v/{pattern}/{command}
如果运行此命令:v/console/d,它将删除所有不包含句点的行"console"。
范围
我们可以传递一个范围。例如,如果我们这样做:
:1,5g/console/d
它会找到"console"第 1 行到第 5 行之间的匹配项。
其他范围变体:
.表示当前行。如果您位于第一行,并且想要指定从当前行到第三行的范围,您可以这样做。它会删除当前行到第三行之间:.,3g/console/d所有匹配的行。"console"$表示当前缓冲区/文件的末尾。如果执行此操作:4,$g/console/d,它将删除第 4 行到文件末尾之间所有匹配的行。+n表示 n 行之后的内容。例如,如果我们在第 2 行输入 n:1,+2g/console/d,它将删除当前行中第 1 行和第 2 行之间的所有匹配项。- 我们可以让范围向前移动。例如:
:4,2g/console/d删除第 4 行和第 2 行之间所有匹配的行。
匹配与不匹配
我们可以将匹配模式与不匹配模式结合起来,例如:
:g/console/v/two/d
这会找到包含“ "console",但不包含”的行"two"。
分隔符
您不必使用/分隔符。您可以使用任何非字母的单字节字符(例如,您可以使用 @、\、,"、|,但 az 无效)。
:g@console@d
如果你的模式包含很多字符,这将非常有用"/"。例如,:g@https://mywebsite.com/stuff@d输入 `\n` 比输入 `\n` 更容易:g/https:\/\/mywebsite.com\/stuff/d。
正则表达式
我不会深入讲解正则表达式。但全局命令模式接受正则表达式。例如,要查找双引号内的匹配项:
:g/"[^"]*"/d
解释:
"= 字面引用[^"]*= 除引号以外的任何字符。这是正则表达式中的常见模式。
默认命令
我们一直使用 `(`)`d作为命令。但如果我们不指定任何参数{cmd},全局命令p默认使用 `(`)。
例如:
:g/console
一个使用场景是,如果你的待办事项列表分散在文件中,你可以使用它:g/TODO来显示所有待办事项。
顺便提一下,有个很酷的小知识:因为默认命令在p没有{cmd}指定参数的情况下会使用 `--no ...
:g/re/p
g= 全局re= 正则表达式模式p打印,默认命令
你注意到拼写错误了吗?
它拼写的是“grep” ——就是grep你命令行里的那个工具。
这并非巧合。这条命令最初来自Ed Editor,最早的几款行式文本编辑器之一。而Grep 的名字也来源于 Ed。这简直就是一棵血脉相连的树!
常用命令列表
全局命令使用了Ex编辑器中的许多命令。我将介绍其中一些常用的命令。
删除
再次强调,删除的语法是::g/re/d。
这是一个很有用的命令:
- 删除空白行
:g/^$/d/^$/是空行的正则表达式(行首,,^后跟行尾$)- 更棒的是,
:g/^\s*$/d它还能删除含有空格的行。
代替
替换是另一个重要的功能。如果你是 Vim 用户,你可能已经:s广泛使用过 `( :h substitute`)`。在这里,你可以将其s与全局命令结合使用。
要将所有值替换"const"为"let",我可以这样做:
:g/const/s/const/let/g
这段文字的意思是:“找到所有匹配的行"const",然后将替换"const"为"let"。”
有些人可能会觉得:g/const/s/const/let/g打字很麻烦。为什么要打const两次呢?幸运的是,Vim 意识到了这一点,所以你可以直接这样做:
:g/const/s//let/g
如果将第一个替换参数留空,//则替换将使用全局命令模式。
移动
您可以使用它m来移动比赛结果(更多信息请参见:h :move:)。语法很简单:
:g/pattern/m destination
要将包含“#”的所有行移动"console"到文件末尾,请执行以下操作:
:g/console/m $
这里有一个很有用的例子:
:g/^/m 0反转整个缓冲区。^是行的开头,因此它将匹配缓冲区中的每一行。
放
Put 函数允许您从寄存器 x() 中写入文本:h :put。基本语法:
:g/pattern/pu {register}
如需复习注册流程,请查看:h registers。
假设您的注册表中存储了以下内容a:// Test comment。要将该行自动添加到“console”文本之后,请执行以下操作:
:g/console/pu a
你不必总是从注册表粘贴内容。你可以使用put以下命令输出你自己的文本:
:g/console/pu =\"//Test comment\"
这样会在每个控制台之后添加内容//Test comment。遗憾的是,我们必须转义"。
复制
Vim 有复制方法(:h :copy)。配合 g 命令使用t。基本语法:
:g/pattern/t {address}
它会将所有匹配的模式复制到地址。
一种使用场景是,如果你想将所有内容复制"console"到缓冲区末尾:
:g/console/t $
普通的
`normal( :h :normal)` 不是 Ex 命令。它允许你执行 Vim 的普通模式命令。语法为:
:g/pattern/normal {normal-mode-command}
如果你想用 . 注释掉所有行,"console"可以使用 Vim 的全局 + 普通模式:
:g/console/normal I//
Vim 将找到所有包含的行"console"并执行I//(进入插入模式,在行中第一个非空格之前,添加//)。
Vim 普通命令的强大之处在于,它可以运行普通模式下可以运行的任何命令,包括宏(:h :q)。
如果我们想用宏来替换所有const内容let,方法如下:
首先,创建一个宏来更改const。let将光标放在第一行顶部,第一个字符:
qqciwlet<Esc>q
解释:
qq= 在 q 寄存器上启动宏ciw= 更改内部单词(删除“const”并进入插入模式)let<Esc>输入“let”,进入正常模式q= 停止宏
宏q准备就绪后,选中剩余部分"const",并对每一行执行该宏:
:g/const/normal @q
种类
你可以将 g 和 sort( :h :sort) 结合使用。坦白说,我发现直接在可视化模式下使用 sort 更方便。如果你只有一两项需要排序,最简单的方法是进入可视化模式,选中它们,然后运行 sort() :sort。
不过,我有一个使用场景比较常见,我想在这里提一下。
这次演示中,我们需要使用不同的文本。
const someArr = [
"i",
"g",
"h",
"b",
"f",
"d",
"e",
"c",
"a",
]
const someMoreArray = [
"h",
"b",
"f",
"d",
"e",
"c",
"a"
]
// and more
假设你有一个包含数百个此类数组的大文件。你希望对每个数组中的元素进行排序,但不需要对数组本身进行排序。
我们可以使用全局命令来仅针对每个数组中的元素执行操作sort。命令如下:(:g /\v\[/ +1,/\v\]/-1 sort 我在上一篇文章中做过类似的事情,但让我再解释一下):
该命令由 3 个部分组成:
:g /\v\[/ +1,/\v\]/-1 sort
^--1st ^--2nd ^--3rd
第一点是我们的模式。第二点和第三点是我们的指令。让我解释一下:
回顾一下我们的g命令语法:
:g/{pattern}/{command}
我们的模式是:
/\v\[/
- 它使用了 Vim 的神奇功能(
:h magic) \[找到[与数组的方括号开口匹配的项。
我们的命令是:
+1,/\v\]/-1 sort
这实际上包含两部分:
[range] {cmd}
我没有告诉你的是,我们还可以将一个额外的范围传递给我们的命令。
我们的命令范围是:
+1,/\v\]/-1
我们的命令是:
sort
该命令的作用如下:
- 我们的
g命令模式是[,数组开头。 - 我们对每个模式执行命令
sort。 - 该命令有自己的范围,从匹配项之后的行开始
[,到匹配项之前的行结束]。 - 它的性能
sort在这个范围内。
如果你对这种形式感到困惑,别担心。我第一次学习这种方法时,也盯着屏幕看了10到15分钟,试图理解,但一无所获。慢慢来,过几天再仔细想想。
持续学习的技巧
学习 Vim 是一项长期投入。以下是一些提升技巧的建议:
- 当你在处理重复性任务时,有没有更好/更快/更程序化的方法?很有可能是有的。
- 阅读 Vim 文档
:help,在线搜索和提问。 - 当你掌握方法时,一开始会很笨拙也很慢。反复练习,直到你能几乎不用思考就能完成。
祝您编程愉快!
友情提示:如果你喜欢这篇文章,那么有98.39%的概率(未经科学验证)你也会喜欢我的《Vim食谱:美食Vim》。快来看看吧!
文章来源:https://dev.to/iggredible/discovering-vim-global-command-49ad