我想在 vim 中定义一个映射,它在文件中搜索一个特殊位置(使用正则表达式),然后执行一个依赖于匹配模式的外部命令。 IE。我在想类似的事情:
:g/set\ "\(.*\)"/!echo 'bla '\1' blubb' > file
或
:g:set\ "\(.*\)":call system("echo 'bla ". submatch(0) ." blubb' > file")
我的目标是在我的文件中搜索像
这样的行set "x=3"
并创建一个包含以下内容的新文件:
bla x=3 blubb
不幸的是,两次尝试(以及其他几次尝试)均无效。谢谢!
编辑:将以下内容添加到我的 .vimrc 也不起作用:
:map <F4> :g:set\ "\(.*\)":call Gnutex(submatch(1))
function Gnutex(str)
return system("echo 'bla ". a:str ." blubb' > file")
endfunction
编辑: 工作解决方案(连同之前的功能):
:% s/set\ output\ "\(.*\)"/\=[submatch(0), Gnutex(submatch(1))][0]/
我认为有更好的解决方案,但这行得通。
最佳答案
\1
和 submatch(0)
表达式作为 :s
的一部分提供命令。它们不会自动用于 :g
命令。
有点像
:g/set ".*"/execute "!echo 'bla" matchstr(getline("."), 'set "\zs.*\ze"') "blubb' > file"
应该可以。 (我在没有“> 文件”部分的情况下进行了测试。)
请注意,您不必将“”(空格)作为正则表达式的一部分进行转义。
关键是:g/<pattern>/
之后的部分应该是一个 ex 命令,它会做你想做的事。在这种情况下,我使用 getline()
获取当前行, 用 matchstr()
对其进行处理(比 substitute()
更简单但不够灵活)和 :execute
结果。
你应该能够用 :call system()
做类似的事情.
我认为 :g
设置搜索寄存器,因此您可以使用 @/
避免将正则表达式写出两次在matchstr()
或 substitute()
称呼。在上面的示例中,我删除了 \(
分组 \)
字符,但如果您想尝试这种方法,您应该恢复它们。
关于regex - 在外部命令中使用匹配模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21559564/