如何将Vim用作多行grep并在Shell脚本中获取完整匹配结果?
用Vim实现多行Grep及脚本化输出
能否用Vim作为多行Grep工具?
当然可以。Vim的正则引擎支持跨行匹配(通过\_元字符匹配包含换行的任意字符),结合全局命令:g(global),完全能实现比普通grep更灵活的多行模式匹配,尤其适合处理带跨行结构的代码片段(比如你提到的多行函数调用)。
解决脚本中Vim仅输出单行匹配的问题
你当前的命令只打印第一行,原因是:g/.../p里的:p命令默认仅输出光标所在的起始行,即便正则匹配了跨行内容,也不会自动输出后续行。要完整输出整个多行匹配块,可以通过以下两种方法修改命令:
方法1:通过匹配位置获取多行内容
利用getmatchpos()获取匹配的起始/结束行,再打印对应行的内容:
vim -es -c ":g/function(\_.\{-})/let [sline, _, eline, _] = getmatchpos() | echo join(getline(sline, eline), '\n')" -c ":q!" file.c
getmatchpos()返回匹配的起始行、起始列、结束行、结束列,我们提取其中的sline(起始行)和eline(结束行)getline(sline, eline)获取这两行之间的所有内容join(..., '\n')将行内容用换行符拼接,保证输出格式和原文件一致
方法2:结合可视模式复制并输出匹配块
通过normal! gvy选中整个匹配块并复制,再输出寄存器内容:
vim -es -c ":g/function(\_.\{-})/silent! normal! gvy | echo @0" -c ":q!" file.c
gv会选中当前匹配的整个文本块(包括跨行内容),y将其复制到默认寄存器@0引用最近一次可视模式复制的内容,echo输出到stdoutsilent!避免Vim输出冗余的状态信息
补充说明
-es参数让Vim以静默的Ex模式运行,不会打开图形界面,适合脚本调用- 你的正则
function(\_.\{-})已经正确使用了非贪婪匹配\{-},能准确匹配到第一个闭合括号),避免匹配嵌套括号的多余内容
内容的提问来源于stack exchange,提问作者Ivan Dimitrov
相关产品推荐
相关产品推荐

