Vim :s 替换一行中出现的第一个 N < g 次

Kev*_*vin 14 vim search replace

在 vim 中,我有时有机会替换一行中匹配的前几次出现,但不是每个人都喜欢g。例如:

a a a a a
Run Code Online (Sandbox Code Playgroud)

b b b a a
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用:s/a/b/[enter]:[up][enter]:[up][enter],但是重复 3 次就够乏味了,我有可能有 10 多个替换的行。
我试过了:

  • :s/a/b/3g: vim 抱怨尾随字符。
  • :s/a/b/3: 更改此行和以下两行的第一次出现。
  • 3:s/a/b: 和以前一样。
  • :s/a/b/g3: 更改此行和接下来的两行中出现的所有内容。
  • :3s/a/b: 更改第 3 行的第一次出现。
  • :/a/,3/a/s/a/b:更改文件中a包含的下一行和第三行之间的每一行的第一次出现a(必要时提示反转)。
  • :/a/,/\([^a]*a\)\{3\}/s/a/b/: 更改此行和下一行之间每行的第一个匹配项,其中包含 3a秒(这不容易扩展到多字符搜索)。

以及其他各种寻址模式,都没有奏效。我必须说,我已经学到了很多关于:s试图找到这个问题的答案的命令,但我仍然没有解决它。

有人知道怎么做吗?

(特定范围的奖励积分,例如第二次到第四次出现)

jw0*_*013 10

基于:s/pattern/replacement/gc Samus_想法(当模式包含在替换字符串中时,这似乎是确保正确操作的最简单方法),在一行中替换第 2 次到第 4 次出现:

:call feedkeys("nyyyq") | s/pat/string/gc
Run Code Online (Sandbox Code Playgroud)

feedkeys()是一个将输入字符串填充到键盘输入队列的函数。重点是预先进行计数,这样您就不必担心计数失败或被打扰。

对于更一般的情况,要替换单行中第 MN次出现的N大于或等于非常大的M

:call feedkeys(repeat("n", M-1) . repeat("y", N-M+1) . "q") | s/pat/string/gc
Run Code Online (Sandbox Code Playgroud)

用你想要的值替换MNvim如果你不想自己做,你甚至可以让你做一些微不足道的心算)。请注意,这.是 VimL 的字符串连接运算符。显然,这只会节省大M 的击键次数。如果您经常使用此功能,那么将上述内容放入某种自定义命令或函数中可能会节省您的时间,因为它需要大量输入。


小智 8

对于第一个问题,我会这样做:

:s/a/b
&&
Run Code Online (Sandbox Code Playgroud)

第二个更棘手,我不知道如何自动执行此操作,但您可以让 vim 在每次匹配时提示您,如下所示:

:s/a/b/gc
Run Code Online (Sandbox Code Playgroud)

然后您对前 n 个匹配回答“否”,对其他匹配回答“是”。


kev*_*kev 6

a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a

:3,6g/^/let i=0 | while i<3 | s/a/b/ | let i+=1 | endwhile

a a a a a
a a a a a
b b b a a
b b b a a
b b b a a
b b b a a
a a a a a
Run Code Online (Sandbox Code Playgroud)