我发现自己经常遇到需要结合正则表达式、某种移动以及复制和粘贴的问题。我确信在 vim 中有一些方法可以做到这一点,但我还没有看到任何东西将它们组合在一起。作为一个例子,我现在试图解决的问题是这样的。
- 查找 /^Description "(.*)"/ 的行
- 保存捕获的文本
- 转到 /^TEXT "(.*)-/
- 将上面捕获的文本替换为步骤 2 中捕获的文本
- 根据需要重复通过文件向前移动
有谁知道在 VIM 中快速自动化此类任务的方法?
我发现自己经常遇到需要结合正则表达式、某种移动以及复制和粘贴的问题。我确信在 vim 中有一些方法可以做到这一点,但我还没有看到任何东西将它们组合在一起。作为一个例子,我现在试图解决的问题是这样的。
有谁知道在 VIM 中快速自动化此类任务的方法?
您可以将以下序列映射到未使用的键(例如 F2),然后按您想要的次数。
:map <F2> /^Description "(.*)"<CR>y//e/^TEXT "(.*)-<CR>Pd//e
或者,您可以添加<F2>
到末尾,以便它将递归运行,直到匹配失败。
:map <F2> /^Description "(.*)"<CR>y//e/^TEXT "(.*)-<CR>Pd//e<F2>
让我们分解一下,看看发生了什么。这将移动到您第一次搜索的开头:
/^Description "(.*)"<CR>
这会一直拖到您的第一次搜索结束。
y//e
这是您的第二次搜索:
/^TEXT "(.*)-<CR>
这会将您拉出的内容放在光标之前,向右移动一个字符,然后删除,直到您的第二次搜索结束。
Pld//e
我还没有学会所有新奇的 vim-only 功能。我在 vim 之前学习了 vi,这个解决方案适用于任何 vi-ish 编辑器。也许使用 vim 功能可能会有更好的解决方案。
在这种情况下,我通常会使用该:map
命令绑定多个键,每个键都执行上述操作。你需要挑选一些你可以暂时不用的钥匙;我经常为此使用g
和。v
@Neil Forrester 建议使用功能键,这是个好主意。
现在,您展示了带有指示匹配组的括号的正则表达式模式。(在 vi 或 vim 中,您实际上需要在每个括号之前放置一个反斜杠以使其“具有魔力”;请参阅文档。)但是,对于此解决方案,我将改为使用f
命令,该命令 (f) 找到指定的特点; 和/或t
命令,它会跳过一个字符。 f
跳到一个字符,在t
一个字符之前跳转。因此,f"
我们可以跳转到字符串的第一个双引号,然后使用t"
我们可以跳转到第二个双引号之前。所以,序列f"lyt"
会找到第一个双引号,向右移动一个字符,然后将所有内容拉到下一个双引号。但是,让我们将抽出的文本存储到 26 个命名缓冲区之一中;让我们只使用缓冲区“a”:f"l"ayt"
这有点令人困惑,因为我们必须使用"a
来引用命名缓冲区“a”,但我们还有很多其他"
字符需要查找。
此外,在“地图”中,您可能需要记录 Enter 键的击键。您这样做的方法是按 Ctrl+V,然后按 Enter 键。这将显示为^M
。在我下面的代码中,如果您看到^M
它并不意味着实际^
后跟实际M
,而是表示表示 Enter 键的单个键。
所以现在,我们可以进行两个键映射。让我们绑定v
执行步骤 1 和 2,以及g
执行步骤 3 和 4。
:map v /^Description "/^Mf"l"ayt"
:map g /^TEXT "/^Mf"ldt""aP
不要忘记,使用 Ctrl+V 和 Enter 而不是实际输入 ^M,因此您不能只复制/粘贴以上内容而不进行编辑。
现在,使用v
键执行第 1 步和第 2 步,使用 键执行第g
3 步和第 4 步。通过交替敲击这两个键,您可以快速完成很多操作。
也可能有一种方法可以通过在 vim 中使用脚本来做到这一点,但另一方面,如果你想编写脚本,你可能只想编写一个简短的 Python 脚本(或你最喜欢的语言)。上面的两个关键宏确实提供了一种在 vim 中执行此类操作的快速方法。
vim 具有某种功能,可以在您键入时记录键,我认为可以使用它来快速创建这种宏。