【问题标题】:Find and replace strings in vim on multiple lines在 vim 中多行查找和替换字符串
【发布时间】:2013-11-28 11:35:10
【问题描述】:

我可以使用:%s/<search_string>/<replace_string>/g 替换文件中的字符串,或者使用:s/<search_string>/<replace_string>/ 替换当前行。

如何在 vim 中选择和替换选定行中的单词?

示例:替换行 6-1014-18 中的文本,但不替换 11-13 中的文本。

【问题讨论】:

标签: vim vi


【解决方案1】:

你可以用两个查找/替换序列来做到这一点

  :6,10s/<search_string>/<replace_string>/g
  :14,18s/<search_string>/<replace_string>/g

第二次你需要调整的只是范围,所以我不会全部输入,我会回忆最后一个命令并只编辑范围

【讨论】:

    【解决方案2】:

    全部替换:

    :%s/foo/bar/g
    

    找出所有出现的“foo”(在所有行中),并将其替换为“bar”。

    对于特定的行:

    :6,10s/foo/bar/g
    

    将第 6 行到第 10 行(含)的所有行的每个 'foo' 更改为 'bar'。

    【讨论】:

    • 这里 /g 的目的是什么?对不起,我是 linux 新手
    • @RajaAnbazhagan 这个表达式的最后一部分,在最后一个 / 之后,是您指示操作标志的地方。此命令通常会替换一行中的 first 匹配项;使用g 标志,它将替换所有出现。
    • 如果您要复制并粘贴他人的作品,您应该真正参考您的来源(即 vim.wikia.com/wiki/Search_and_replace)。
    • % 的东西起作用了!否则,它只是第一次出现。
    • % => 在所有行上运行此命令。 g => 匹配同一行中的多次出现。
    【解决方案3】:

    :&amp;&amp; 命令使用相同的标志重复上次替换。您可以为其提供额外的范围(并连接任意数量):

    :6,10s/<search_string>/<replace_string>/g | 14,18&&
    

    如果你有许多范围,我宁愿使用循环:

    :for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor
    

    【讨论】:

    • 谢谢。给未来用户的注意事项 - :6,10s/&lt;search_string&gt;/&lt;replace_string&gt;/g | :14,18&amp;&amp; | :20,23&amp;&amp; | :28,31&amp;&amp; 也可以使用,for 循环使它更容易记住和执行。
    • 很高兴你喜欢它!后续命令中的: 是可选的,顺便说一句,因此您可以节省更多击键。
    • :&amp;&amp; 每周将为我节省数百次击键。谢谢!
    • 它在我的 vim 末尾没有“g”的情况下工作。所以也许当你指定行范围时它不需要全局标志
    • @TayyarR 范围覆盖了行(可以说是垂直),而“g”标志确定是否只替换行内的一个或所有匹配项(因此水平)。
    【解决方案4】:

    作为旁注,无需输入行号,只需在其中一种可视模式中突出显示要查找/替换的行即可:

    • VISUAL 模式(V
    • VISUAL BLOCK 模式(Ctrl+V
    • VISUAL LINE 模式(Shift+V,最适合您的情况)

    选择要替换的行后,输入命令:

    :s/<search_string>/<replace_string>/g
    

    您会注意到,'&lt;,'&gt; 范围会自动为您插入:

    :'<,'>s/<search_string>/<replace_string>/g
    

    这里'&lt; 仅表示第一个突出显示的行'&gt; 表示最后一个突出显示的行

    请注意,在 NORMAL 模式下可能会出现意外行为:'&lt;'&gt; 指向在 @ 之一中完成的最后一个突出显示的开始和结束987654332@ 模式。相反,在NORMAL模式下,可以使用特殊的行号.,它只是表示当前行。因此,您只能像这样在当前行上查找/替换:

    :.s/<search_string>/<replace_string>/g
    

    另外需要注意的是,在范围和查找/替换命令之间插入第二个: 并没有什么坏处,换句话说,这些命令仍然有效:

    :'<,'>:s/<search_string>/<replace_string>/g
    :.:s/<search_string>/<replace_string>/g
    

    【讨论】:

    • > 示例:替换第 6-10 行、第 14-18 行的文本,但不替换第 11-13 行的文本。 ——你的回答不是回答了这个问题吗?
    【解决方案5】:
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    /sys/sim/source/gm/kg/jl/ls/owow/lsal
    

    假设你想用其他一些信息替换上面的内容。

    COMMAND(:%s/\/sys\/sim\/source\/gm\/kg\/jl\/ls\/owow\/lsal/sys.pkg.mpu.umc.kdk./g)

    在此将替换为 (sys.pkg.mpu.umc.kdk.)。

    【讨论】:

    • 我不确定这是否真的回答了这个问题。从这个问题看来,提问的人已经知道如何使用%s 来修改输入,但想知道如何“半全局”地进行(即他的规范是第 6-10 和 14-18 行,但不是第 11-13 行)。
    • 什么是“命令”?而你正在遭受leaning toothpick syndrome的痛苦。
    • 要治愈这种综合症,您可以使用另一个字符作为分隔符,而不是默认的/,例如!@_:%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
    【解决方案6】:

    VI搜索替换命令示例

    假设您想找到一个名为“foo”的单词并替换为“bar”。

    第一次点击[Esc]

    键入:(冒号)后跟%s/foo/bar/,然后按[Enter]键

    :%s/foo/bar/

    【讨论】:

    • 您的:%s/&lt;search_string&gt;/&lt;replace_string&gt;/g 命令将替换整个文件中的所有匹配项。不完全是问题的答案,但仍然有用:)
    • @tanius 实际上这是对我的问题最直接的回答。您可以考虑将问题修改为“Find and replace strings in vim on "Selected" lines”
    【解决方案7】:

    通过视觉选择指定范围是可以的,但是当有非常 只需几行即可选择的简单操作 最好的操作符是将这些命令作为操作符应用。

    遗憾的是,这不能通过标准的 vim 命令来完成。你可以做一个排序 的解决方法! (过滤器)运算符和任何文本对象。为了 例如,要将操作应用于段落,您可以这样做:

    !ip
    

    这必须读作“在段落中应用运算符!”。过滤器 操作员启动命令模式并自动插入行的范围 后跟一个文字“!”您可以在之后删除。 如果您将此应用于以下段落:

    1
    2  Repellendus qui velit vel ullam!
    3  ipsam sint modi! velit ipsam sint
    4  modi! Debitis dolorum distinctio
    5  mollitia vel ullam! Repellendus qui
    6  Debitis dolorum distinctio mollitia
    7  vel ullam! ipsam
    8
    9  More text around here
    

    按“!ap”后的结果是:

    :.,.+5
    

    作为'.' (point) 表示当前行,当前行之间的范围 行和后面的 5 行将用于操作。现在您可以添加 替换命令的方式与之前相同。

    不好的部分是这并不容易为后者选择文本 应用运算符。好的部分是这可以重复插入 其他类似文本范围(在本例中为段落)的范围 大小明显不同。即,如果您以后想选择更大的范围 段落'.'会正确的。

    另外,如果您喜欢使用语义文本对象来选择 操作范围,可以查看我的插件 EXtend.vim 可以做同样的事情 但以更简单的方式。

    【讨论】:

      【解决方案8】:

      在 vim 中,如果你对哪些行会受到影响感到困惑,请在下面使用

       :%s/foo/bar/gc  
      

      将每个 'foo' 更改为 'bar',但首先要求确认。 按“y”表示是,按“n”表示否。之后别忘了保存

      :wq
      

      【讨论】:

      • 除了指定范围之外,您实际上还可以使用c 标志,因此:6,10s/&lt;search_string&gt;/&lt;replace_string&gt;/c 有效。 c 代表 confirm。我经常使用c 标志来防止意外替换我没想到它们也存在的单词。
      【解决方案9】:

      我们无需费心输入当前行号。

      如果您想将当前行 (.) 和下两行 (+2) 的每个 foo 更改为 bar,只需执行以下操作:

      :.,+2s/foo/bar/g
      

      如果您想在进行更改之前进行确认,请将g 替换为gc

      :.,+2s/foo/bar/gc
      

      【讨论】:

      • 我经常使用的另一个好东西是:.,$s/foo/bar/gc 用于从当前行开始搜索和替换文件。
      【解决方案10】:

      回答这个问题:

      :40,50s/foo/bar/g

      在第 40 行和第 50 行(含)之间的这些行中,将 foo 替换为 bar,当执行此命令时,您当前可以在任何行中。

      :50,40s/foo/bar/g

      也可以,vim 会要求你确认,然后像你输入第一个命令一样为你替换。

      :,50s/foo/bar/g

      在您当前所在行和第 50 行(含)之间的这些行中,将 foo 替换为 bar。 (如果你在第 50 行之后的一行,vim 会再次要求确认)

      明确vim和Eclipse的vrapper插件的区别:

      请注意,在 varpper 中

      :,50s/foo/bar/g 命令将不起作用。

      :50,40s/foo/bar/g 无需确认即可工作。

      (适用于 Vrapper 0.74.0 或更早版本)。

      【讨论】:

        【解决方案11】:

        搜索和替换

        :%s/search\|search2\|search3/replace/gci
        

        g => 全局搜索

        c => 请先确认

        i => 不区分大小写

        如果您想直接替换而不确认,请使用以下命令

        :%s/search/replace/g
        

        如果您想确认每次替换,请运行以下命令

        :%s/search/replace/gc
        

        请先确认,此处搜索不区分大小写。

        :%s/search/replace/gci
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-24
          • 1970-01-01
          • 2020-09-29
          • 2011-08-22
          • 2015-09-22
          • 2019-06-24
          • 2016-01-13
          相关资源
          最近更新 更多