Vim搜索和替换 - 限制在某些行

时间:2012-06-22 19:21:27

标签: vim replace

我有一种情况,我想通过文件替换FOO;但是,我只想在某些地方这样做,比如68-104,500-537和1044-1195之间。在实践中,我在感兴趣的行上删除了标记(ma,mb,mc,...),然后运行了以下内容:

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

我不得不用不同的搜索和替换术语s / CAT / DOG等重复这几十次,这变得很痛苦,每次都必须重新编写命令行。我很幸运,我只有3个地方,我想限制我的搜索(想象如果有30或40,命令行会有多乱)。

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

相关说明。我将FOO复制到's'(搜索)寄存器,将BAR复制到'r'(替换)并尝试命令行

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

这样可以让我每次都不得不重新编写命令行,但是它不起作用。替换位很好\ = @ r,但搜索模式中的\ = @ s给出了错误。

任何提示都将不胜感激。

7 个答案:

答案 0 :(得分:5)

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

我通常这样做的方法是在第一行执行>G之类的缩进整个文件,然后使用:s/^ /X/命令或block-visual用X替换前导空格在我想要的线上。

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

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

最后,删除临时前缀。

答案 1 :(得分:4)

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

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

答案 2 :(得分: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来添加忽略错误消息,如果不清楚在相应的行块上找到替换。

答案 3 :(得分:2)

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

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

这应该会使你的工作更轻松,更清晰。

答案 4 :(得分:2)

使用q:,您可以调用以前的命令行并将其编辑为普通的Vim缓冲区,这样您就可以用其他内容快速替换FOOBAR,然后重新执行输入

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

答案 5 :(得分:2)

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

  1. 折叠每个区域
  2. 将光标放在一个封闭的折叠上
  3. 执行替换::s/foo/bar<CR>
  4. 使用zjzk
  5. 移至下一个已关闭的折叠
  6. 使用命令行历史记录::<C-p><CR>:<Up><CR>执行相同的替换
  7. 重复...
  8. 您还可以在替换结尾处添加c标记,以便Vim在实际执行之前要求您进行确认。如果您有很多比赛,这可能会很乏味。

答案 6 :(得分:0)

这是最简单的方法

:5,10s/old/new/g

5,10:startlinenum,endlinenum