Vim 仅在找到匹配项的行中替换

Vim 仅在找到匹配项的行中替换,vim,sed,regex,Vim,Sed,Regex,在中,如何仅在字符串匹配的特定行上替换单词?例如,我有 replace here: foo but not here: foo replace again here: foo 我想在找到字符串replace的所有行上用bar替换foo,即输出应该是 replace here: bar but not here: foo replace again here: bar 受的启发,类似的语法的搜索和替换,我期待 :/replace/s/foo/bar/ 工作,但它仅在与replace匹配的第一

在中,如何仅在字符串匹配的特定行上替换单词?例如,我有

replace here: foo
but not here: foo
replace again here: foo
我想在找到字符串
replace
的所有行上用
bar
替换
foo
,即输出应该是

replace here: bar
but not here: foo
replace again here: bar
受的启发,类似的语法的搜索和替换,我期待

:/replace/s/foo/bar/

工作,但它仅在与
replace
匹配的第一行进行替换。如何将其扩展到整个文档?

您可以使用
g
命令(全局)在多行中对其进行更改:

:g/replace/s/foo/bar/

为了精通vim,必须了解如何分解问题并建立答案。您还必须学习vim的一些基本操作

例如,一旦您将“如何删除到行尾?”分解为两个问题,您就会意识到这只是“如何删除一系列字符?”和“如何将光标移动到行尾”的一种情况。然后,当您学习更多的更改命令和更多的运动命令时,您就再也不用问了

对于当前的问题,您应该将其分解为“如何替换一行中的单词?”和“如何在多行上执行命令?”

您已经知道第一部分的答案:
:s/foo/bar
。(有些人会本能地添加
/g
,以替换线上的所有比赛。“高尔夫”玩家喜欢用尽可能少的字符完成任务的游戏。)

第二部分的答案是使用
:global
命令(缩写
:g
)。它可以用于在与模式匹配的所有行上执行(几乎)任何Ex命令。您也可以使用
:g
:v
在与模式不匹配的所有行上执行命令。所以你最初问题的简短答案是

:g/replace/s/foo/bar
虽然您的建议有一个字符不同(不包括可选的、尾随的
/
),但它是非常不同的。初始值
/replace/
指定了一个范围

我认为很多人使用
:g/{pat1}/s/{pat2}/{expr}/
,但从未意识到它可以被分解,他们可以使用
:s
以外的命令

进一步阅读:

:help :global
:help [range]
:help repeat.txt

:s/foo/bar/g
中,
g
是一个标志。在
:g/replace/…
中,
g
是一个命令。从长远来看,如果你理解其中的区别,你会更有效地使用vim。好的观点,@benjifisher:不是一个标志,而是一个命令。让我纠正一下我的语言。我正在以“%s/(].*)的形式进行替换\@