如何通过grep选项准确捕获匹配括号包裹的代码片段?
问题:如何用grep精准匹配带嵌套括号的C++代码块?
我有一段结构如下的C++代码:
foo ( bar ( foo0(<任意数量的括号可能出现在这里>) ), foo1bar(<任意数量的括号可能出现在这里>) )
目前我用这个命令来捕获代码:
grep -A15 -E "foo[[:space:]]*$" <file_name>
靠指定后续15行来确保覆盖完整代码块,但这种方法不够准确。我想要统计foo之后的括号开闭数量,找到对应的闭合括号后就立即停止搜索。请问能不能不用编写完整脚本,仅靠grep的选项实现这个需求?
示例文件内容
... foo ( bar ( a(b) ), c(d) ) ... dummy ( nextDummy() ) ...
注:...代表不含(或)的代码行。
期望输出
foo ( bar ( a(b) ), c(d) ) dummy ( nextDummy() )
回答
仅靠grep的原生选项做不到这个需求。因为grep是基于行的文本匹配工具,没有内置的嵌套括号计数逻辑,它没法跟踪括号的嵌套层级,只能做简单的正则匹配或固定行数的范围选取。
如果不想写复杂脚本,可以用awk来实现,单行命令就能搞定,比写脚本简单很多。针对你的需求,匹配foo和dummy开头的代码块,命令如下:
awk '/^(foo|dummy)[[:space:]]*$/ { print; getline; print; count = 1; while (count > 0) { getline; if (index($0, "(") != 0) count++; if (index($0, ")") != 0) count--; print; } }' <file_name>
命令说明
- 先匹配以
foo或dummy结尾(后面可跟任意空格)的行,打印该行 - 读取并打印下一行(也就是开括号
(所在的行) - 初始化括号计数为1(因为已经读到一个开括号)
- 循环读取后续行:每遇到
(计数加1,遇到)计数减1,直到计数为0时停止,过程中打印所有行
如果只需要匹配foo的代码块,把正则里的^(foo|dummy)改成^foo即可。
内容的提问来源于stack exchange,提问作者Naghi
相关产品推荐
相关产品推荐

