vim range .+1,$包括当前行,影响一行太多

vim range .+1,$ includes current line, affecting one line too much

我有一个 vim 脚本来帮助 Python 代码重构;根据文件的不同,它会插入多个相等的 import 行,例如如果许多行更改为使用 getToolByName.

,则会出现多次 from Products.CMFCore.utils import getToolByName

为了清理,我在脚本末尾添加了如下几行:

normal gg
/^\(from AccessControl import Unauthorized\>\)\?/
.+1,$s,^from AccessControl import Unauthorized\n,,e
normal gg
/^\(from Products.CMFCore.utils import getToolByName\>\)\?/
.+1,$s,^from Products.CMFCore.utils import getToolByName\n,,e

想法是:

为了避免错误(这会 造成很大伤害,尤其是在通过 :argdo 使用脚本时),我将搜索设为可选 (\?) ,因为 e 标志仅适用于 :s 命令。如果该搜索未找到真正的匹配项,则以下 :.+1,$ s 命令也不应删除任何内容,因为它更具限制性。

(剩余的插入行需要手动移动)

但是,由于 \?,替换不仅删除了以下出现的事件 (.+1),而且删除了 所有 - 包括我第一次出现的想留着。

我该如何解决这个问题?

基于 sed 的解决方案也会对我有所帮助。

版本: vim v7.4 (CentOS Linux) 和 Windows.

上的 gvim 8.1 同样的问题

谢谢!

编辑: 现在我有了一个解决方法,我仍然对不需要临时更改的“适当”解决方案感兴趣,因此 vim 认为文件 未更改 如果一切已经很好了

这可能不是最佳解决方案,但这是我找到的解决方法:

在第一行 normal gg 上面,我添加了代码以在文件末尾添加两行:

normal GoELEPHANT IN CAIRO
normal yyp

然后我将 /.../ 行更改为 无条件地 或者 找到那些额外的行,例如:

normal gg
/^\(from AccessControl import Unauthorized\>\|ELEPHANT IN CAIRO\)/
.+1;$ s/^from AccessControl import Unauthorized\n//e

最后我删除了那些行:

g/^ELEPHANT IN CAIRO$/d

如您所见,问题的发生是因为您搜索 from AccessControl import Unauthorized 时使用的是 ?,这实际上使它匹配 行,并且不是实际导入的第一行。

您可以通过使用与您想要匹配的确切行相匹配的模式来解决此问题,但使用 :silent! 来防止任何错误破坏您的序列。

这可行:

normal gg
silent! /^from AccessControl import Unauthorized\>/
.+1,$s,^from AccessControl import Unauthorized\n,,e

但更好的解决方案是使用一个范围来查找模式并同时从下一行开始。您还可以使用 :d 命令删除一行,并使用 :g//d 删除与特定正则表达式匹配的所有行(范围内)。此外,如果您两次使用相同的模式,那么在 :g 命令上简单地使用 // 将再次匹配相同的模式。

综合起来:

:0/^from AccessControl import Unauthorized\>/+1,$g//d

所以这从第 0 行开始(在文件开头之前,所以它也在文件的第一行匹配),然后找到第一次出现的模式,然后从后面的行开始, 一直到文件末尾查找相同模式的所有其他匹配项,并删除匹配的行。

与之前相同,如果您不想在模式不匹配时看到错误(或者如果只有一个匹配,在这种情况下 :g// 将失败),您可以使用:silent! 再次压制它。

:silent! 0/^from AccessControl import Unauthorized\>/+1,$g//d