8

我有一种情况,我想FOOBAR整个文件替换。但是,我只想在某些地方执行此操作,例如在第 68–104、500–537 和 1044–1195 行之间。在实践中,我将标记放在感兴趣的行(通过mambmc等)并运行以下命令:

:'a,'b s/FOO/BAR/g | 'c,'d s/FOO/BAR/g | 'e,'f s/FOO/BAR/g

我不得不用不同的搜索和替换术语等重复数十次,s/CAT/DOG每次都必须重写命令行变得很痛苦。我很幸运,我只需要将搜索限制在三个地方(想象一下如果有 30 或 40 个命令行会变得多么混乱)。

没有写一个函数,有没有更简洁的方法呢?

在相关说明上。我复制FOOs (搜索)寄存器和BARr 替换)并尝试运行

:'a,'b s/\=@s/\=@r/ | 'c,'d s/\=@s/\=@r/ | 'e,'f s/\=@s/\=@r/

这可以让我不必每次都重写命令行,但是,唉,它没有用。替换位 \=@r很好,但是 \=@s搜索模式中的位给了我一个错误。

任何提示将不胜感激。

4

7 回答 7

5

如果您需要在一堆不同范围的行上执行一组逐行操作(如替换),您可以使用的一个技巧是通过首先添加前缀来使这些行看起来不同(不被任何人共享)的其他行)。

我通常这样做的方法是缩进整个文件,例如>G在第一行执行的操作,然后使用:s/^ /X/命令或块视觉在我想要的行上用 X 替换前导空格。

然后:g结合使用:s。例如:

:%g/^X/s/FOO/BAR/g
:%g/^X/s/BAZ/QUUX/g

最后,删除临时前缀。

于 2012-06-22T19:55:28.223 回答
4

为了摆脱重新键入相同搜索模式、替换字符串和标志的必要性,可以简单地使用 :& 带有& 标志的命令:

:'a,'bs/pat/str/g | 'c,'d&& | 'e,'f&&

(详情请参阅:help :&。)

于 2012-06-23T02:43:43.523 回答
3

受@Vdt 回答的启发:

我不确定,但是您可以将所有替换内容写在一个文件中,然后我认为该文件是该文件的来源。 substitutions.vim

68,104s/FOO/BAR/g
168,204s/FOO/BAR/g
618,644s/FOO/BAR/g
681,1014s/FOO/BAR/g
.
.
.
68,104s/BAZ/BOOO/g
168,204s/BAZ/BOOO/g

然后:so substitutions.vim也许你也可以将它用于相同结构的多个文件。e如果不清楚在相应的行块上找到替换,您可以添加一个以添加忽略错误消息。

于 2012-06-22T20:11:27.133 回答
3

而不是使用标记使用这个:

:68,104s/FOO/BAR/g << substitue from line 68 to 104

这应该会让你的工作更轻松、更清晰。

于 2012-06-22T19:38:07.997 回答
2

当在封闭折叠上执行时,替换仅限于该折叠。

  1. 折叠每个区域
  2. 将光标放在一个闭合的折叠处
  3. 执行替换::s/foo/bar<CR>
  4. zj使用或移动到下一个闭合折叠zk
  5. 使用命令行历史::<C-p><CR>:<Up><CR>执行相同的替换
  6. 重复……</li>

您也可以c在替换结束时添加标志,以便 Vim 在实际执行之前要求您确认。如果您有很多匹配项,这可能会很乏味。

于 2012-06-22T22:07:19.097 回答
2

使用q:,您可以调用以前的命令行并将它们作为普通 Vim 缓冲区进行编辑,因此您可以快速替换FOOBAR其他内容,然后重新执行该行Enter

s/\=@s/\=@r/不起作用;正如您所说,这仅适用于更换部件。但是对于模式,可以使用Ctrl++来插入R CtrlregisterR s的内容,而不是\=@s. 最好使用默认寄存器,那么它很简单s//,但您可能已经知道了。

于 2012-06-22T20:03:19.827 回答
1

这是最简单的方法

:5,10s/old/new/g

5,10 : startlinenum,endlinenum

于 2018-08-30T07:51:05.793 回答