道歉,如果已经发布,因为我找不到答案,即使在vim维基上也是如此。
有没有办法可以在单个:g
搜索中以vim命令行模式运行多个命令?
例如,
:%g/foo/ s/bar/\=@a/g | exe "norm /cat\<enter>\"ayiw"
对于foo
匹配的每一行,(我打算这样做)应该将bar
替换为注册a
的内容,然后然后找到cat
的下一次迭代(即使前面有很多行),并将周围的单词放入寄存器a
。
相反,此特定语法使用初始a
寄存器的当前内容完成subsitution命令,然后在一行上执行正常模式命令(在替换完成后)。
此示例不是我的特定用例,但显示了此功能有用的一个实例。我意识到我可以把它全部放到一个exe
中,即%g/foo/exe "norm :s/bar/\\=@a/g\<enter>/cat\<enter>\"ayiw"
,但我想先做第一种方式,因为我觉得它更灵活。
我更喜欢使用vanilla vim来做这件事,但是如果有一个插件,这是一个不错的选择。有没有人知道是否有语法来做这样的事情?
答案 0 :(得分:1)
好吧“有点”脏,但这对你有用吗?
: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解决方案感兴趣,不一定是oneliner)。
答案 1 :(得分:0)
您可以执行此操作(至少对于应用于一个:g的多个:s命令而言)。示例:
" SHORT STORY TITLES to single word of CapitalizedWords within <h3>s
.,$g/^\L\+$/s/[^A-Z0-9 ]\+//ge|s/\u\+/\L&/ge|s/\<\l\+\>/\u&/ge|s/ \+//ge|s/.*/<h3>&<\/h3>/