![Vim :s 替换一行中前 N < g 次出现](https://linux22.com/image/19745/Vim%20%3As%20%E6%9B%BF%E6%8D%A2%E4%B8%80%E8%A1%8C%E4%B8%AD%E5%89%8D%20N%20%3C%20g%20%E6%AC%A1%E5%87%BA%E7%8E%B0.png)
在 vim 中,我有时会替换一行中匹配项的前几次,但不是每个人都喜欢g
。例如:
a a a a a
到
b b b a a
我知道我可以使用: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/
:更改此行与下一行之间每行的第一个出现位置,a
其中包含 3 个(并且这不容易扩展到多字符搜索)。
还有其他各种寻址模式,但都不起作用。我必须说,我已经了解了相当多的有关该:s
命令的知识,试图找到这个问题的答案,但我仍然没有解决它。
有人知道怎么做吗?
(特定范围的奖励积分,例如第二次到第四次出现)
答案1
建立在:s/pattern/replacement/gc
萨姆斯的想法_(这似乎是当替换字符串中包含模式时确保正确操作的最简单方法),替换单行上的第二个到第四个匹配项:
:call feedkeys("nyyyq") | s/pat/string/gc
feedkeys()
是将输入字符串填充到键盘输入队列中的函数。关键是要预先进行计数,这样您就不必担心记错或被打扰。
对于更一般的情况,替换月通过第N次出现在单行上的次数为氮大于或等于一个非常大的中号:
:call feedkeys(repeat("n", M-1) . repeat("y", N-M+1) . "q") | s/pat/string/gc
代替中号和氮与你想要的值(vim
如果你不想自己做的话,你甚至可以让自己做简单的心算)。请注意,这.
是 VimL 的字符串连接运算符。显然这只能节省大的击键次数中号。如果您经常使用此功能,则将上述内容放入自定义命令或某种类型的函数中可能会节省您的时间,因为输入的内容相当多。
答案2
对于第一个问题我会这样做:
:s/a/b
&&
第二个比较棘手,我不知道自动执行此操作的方法,但你可以让 vim 在每次匹配时提示你,如下所示:
:s/a/b/gc
然后,您对前 n 个匹配回答“否”,对其他匹配回答“是”。
答案3
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
答案4
我认为这可能有效,先替换,然后重复两次:
:s/a/b/
2@: