我唯一使用的 Mac
Mac?除非它是一个 vim 宏。
好吧,所以标题有点钓鱼。虽然人们当然可以自由使用他们想要的任何电脑,但我个人从来不喜欢 Mac。我一直觉得很奇怪,许多 Linux 倡导者抨击微软,但在苹果做同样的事情时却保持沉默。无论如何,这篇文章不是关于那个的——它实际上是关于 vim 宏的,因为 vim 宏几乎是我最接近 Mac——或 Emacs 的东西了。嘿,第一段就引发了两场圣战——还不错。
对于我专栏的常客来说,我使用 vim 作为我的编辑器已经不是什么秘密了。我甚至在过去写过一系列关于使用 vi 风格按键绑定的应用程序的专栏文章。但在本文中,我将重点介绍自从我发现可以使用 Ctrl-[ 代替 Esc 以来,vim 中我最喜欢的节省时间的功能之一:宏。
就像我多年来学到的很多东西一样,我需要遇到一个几乎无法克服的问题,才能学会如何有效地使用 vim 宏并将 vim 宏语法记在脑海中。几年前,我是一个 DNS 系统的管理员,该系统服务于数千个区域。我们正处于迁移到新数据中心的项目中,这意味着需要对数千个 DNS 区域文件进行数十项更改,以将它们指向新站点。幸运的是,我们有时间分阶段进行更改,所以这不是一个孤注一掷的努力。但诀窍是,这些区域文件是多年来由不同的管理员创建的,他们每个人都有自己的风格。这意味着我不能仅仅编写一个脚本来为我进行通用的搜索和替换。除此之外,风险也足够高,我不能容忍脚本中的错误对区域文件造成微妙、无声的破坏。
起初,我只是正面硬刚这个巨大的任务,手工完成,我们决定分 20 个区域一批。我会用 vim 打开一个区域文件,进行更改,然后保存它们。在几轮操作之后,我注意到在很多情况下,我在文件中执行的都是完全相同的按键操作。我会转到文件顶部,更新序列号,然后对一些 IP 和一些记录名称执行一些基本的搜索和替换命令。虽然所有区域都不统一,但我发现我的命令可能只有三四种不同的变体。在这一点上,我决定研究如何使用 vim 宏,并发现我可以只保存少量的宏,并将我的编辑时间从每个区域文件 30 秒或一分钟以及许多按键操作,减少到几秒钟和只需几个按键操作。
本质上,vim 宏允许您记录按键操作,将它们分配给键盘上的特定键,然后在以后播放一次或多次。如果您已经熟练使用 vim 按键操作(我的意思是减少您对 hjkl 进行导航的依赖,并使用像 ^ 和 $ 这样的键来转到行的开头和结尾,使用 w 和 b 来向前和向后跳过一个单词,以及搜索单词来移动到它们),一旦您意识到您正在进行大量的重复按键操作来编辑文件,您就会知道是时候录制一个快速宏来节省您的时间了。
就我个人而言,我发现宏在编辑 DNS 区域文件时特别有用,因为过去我需要在一个区域中添加,比如说,50-100 个新的 A 记录,唯一的区别是主机名和 IP 地址不断递增一。这就是我要在这里用作示例的问题,以向您展示如何使用宏。假设您有一个区域文件,需要添加 50 个 A 记录,从 worker1 指向 10.9.0.15 开始,最终以 worker50 指向 10.9.0.64 结束。手动完成这项单调乏味的任务会让你发疯并浪费一个小时,但使用 vim 宏,只需要几秒钟。
这个特定问题的伟大之处在于它非常适合 vim 宏,因为每一行都只是复制前一行并递增两个数字。首先,编辑文件并手动添加第一行
worker1 IN A 10.9.0.15
如果要添加 worker2 记录,您可能会有两种方法。虽然您可以手动输入所有内容,但您可能会输入 yyp 来 yank worker1 行并将其粘贴到下面。接下来,您可能会按 e 转到 worker1 单词的末尾,按 r2 将 1 替换为 2,然后键入 $ 转到行尾并键入 r6 将 5 替换为 6。这可行,但很难一遍又一遍地重复,因为数字每次都在变化。更好的方法是输入 yyp 来复制和粘贴 worker1 行,并且因为光标现在位于第二行的 worker1 单词上,所以按 Ctrl-a,这在 vim 中会递增一个数字。然后,键入 $ 转到行尾并再次键入 Ctrl-a 以将 15 递增到 16。
这种使用 Ctrl-a 的方法就是您将要处理宏的方式。因此,在只有单行 worker1 行存在且您的光标位于该行上的任何位置时,键入 q 以触发宏录制模式。然后按一个您想要将此宏分配到的键,例如 a 键。您的 vim 屏幕现在将在左下角显示“recording”字样。现在您处于录制模式,您所做的任何按键操作都将被录制,直到您再次按下 q 键。进入录制模式后,键入 yyp 以复制和粘贴第一行。光标实际上在这里处于一个很好的位置,位于行首,但如果您不确定某个操作总是会将您的光标放在正确的位置,那么添加一个 ^ 键以确保光标位于行首也无妨。接下来按 Ctrl-a 递增 worker1,使其变为 worker2。现在键入 $ 转到行尾,然后再次按 Ctrl-a 将 15 递增到 16。最后,键入 q 退出录制模式。
现在您已经将宏分配给了 a 键。要重放您的宏,请确保您的光标现在位于 worker2 行的某个位置,然后按 @a。@ 键告诉 vim 重放分配给您接下来按下的任何键的宏,在本例中是 a。您应该在 worker2 下看到第三行 worker3 A 记录。文件的这一部分现在应该如下所示
worker1 IN A 10.9.0.15
worker2 IN A 10.9.0.16
worker3 IN A 10.9.0.17
虽然您可以只按 @a 47 次,但 vim 允许您在几乎任何命令前加上一个数字,它将执行该命令多次。因此,要完成此文件,请确保您的光标位于 worker3 行的某个位置,然后按 47@a 以查看剩余的行出现。
就是这样。现在您已经有了一个关于宏威力的基本示例,下次您发现自己在文本文件中执行重复性任务时,看看是否可以将其分配给一个临时宏。本文只是触及了宏的表面,因此在未来的专栏中,我将跟进更多宏技巧,包括如何以及为什么要嵌套宏。