抱歉,如果这已经发布了,因为即使在 vim wiki 上我也找不到答案。
有没有办法可以在 vim 命令行模式下从单个 :g
运行多个命令搜索?
例如,
:%g/foo/ s/bar/\=@a/g | exe "norm /cat\<enter>\"ayiw"
在匹配
foo
的每一行上,哪个(对于我打算做的)应该, 替换 bar
与寄存器内容 a
, 和 然后 找到 cat
的下一个迭代(即使前面很多行),并将周围的字放入寄存器 a
.相反,此特定语法使用初始
a
的当前内容完成替换命令。 register,然后在一行上执行正常模式命令(替换完成后)。此示例不是我的特定用例,而是显示了此功能有用的一个实例。我意识到我可以把它全部放在一个
exe
中,即 %g/foo/exe "norm :s/bar/\\=@a/g\<enter>/cat\<enter>\"ayiw"
,但我想用第一种方式,因为我觉得它更灵活。我更喜欢使用 vanilla vim 来做到这一点,但如果存在一个插件,这是一个不错的选择。有谁知道是否有语法来做这样的事情?
最佳答案
好吧,有点“脏”,但这对你有用吗?
:let list = split(execute('g/cat/p'), '\n') | g/foo/ s/bar/\=matchstr(remove(list, 0), '\s\d\+\s\zs.*')/g
它首先读取所有出现的
cat
将它们保存在列表中。然后替换第一个
bar
与第一只猫......等等。脏的部分是
matchstr
命令。 g//p
还为结果返回一个数字,因此列表如下所示: 1 cat
2 cat
3 cat
...
这就是为什么我们必须从前面移除一点。我很想听听是否有人知道一个干净的解决方案(我也对干净的 vimscript 解决方案感兴趣,不必是一个单行者)。
关于vim:基于一个 :global 命令运行多个命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45390352/