7

我发现自己经常遇到需要结合正则表达式、某种移动以及复制和粘贴的问题。我确信在 vim 中有一些方法可以做到这一点,但我还没有看到任何东西将它们组合在一起。作为一个例子,我现在试图解决的问题是这样的。

  1. 查找 /^Description "(.*)"/ 的行
  2. 保存捕获的文本
  3. 转到 /^TEXT "(.*)-/
  4. 将上面捕获的文本替换为步骤 2 中捕获的文本
  5. 根据需要重复通过文件向前移动

有谁知道在 VIM 中快速自动化此类任务的方法?

4

2 回答 2

4

您可以将以下序列映射到未使用的键(例如 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
于 2012-05-29T20:38:56.417 回答
4

我还没有学会所有新奇的 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 步,使用 键执行第g3 步和第 4 步。通过交替敲击这两个键,您可以快速完成很多操作。

也可能有一种方法可以通过在 vim 中使用脚本来做到这一点,但另一方面,如果你想编写脚本,你可能只想编写一个简短的 Python 脚本(或你最喜欢的语言)。上面的两个关键宏确实提供了一种在 vim 中执行此类操作的快速方法。

vim 具有某种功能,可以在您键入时记录键,我认为可以使用它来快速创建这种宏。

于 2012-05-29T20:46:04.183 回答