如何从多文件中提取CAKE_FROSTING后的目标字符串?
提取CAKE_FROSTING宏首参数的Bash解决方案
需求说明
从filesToCheck目录下的所有文件中,提取CAKE_FROSTING(后的第一个双引号包裹的字符串,将结果输出到result.txt。
文件示例
file1.cpp
something CAKE_FROSTING("is.simply.the.best", "[no][matter][what]") { DO(something(0) == 1); }
file2.h
something else CAKE_FROSTING( "is.kinda.neat", "[i][agree]") something else something more
file3.cpp
hello
file4.cpp
random_text CAKE_FROSTING("Can be nice") "more random text" CAKE_CREAM("totally.sucks", "[trust][me]")
fileEmpty.h
期望输出(result.txt)
is.simply.the.best is.kinda.neat Can be nice
错误尝试
之前执行的命令仅能处理单个文件,且提取结果错误:
awk '"CAKE_FROSTING\\("{print $2}' filesToCheck/file1.cpp
问题在于:
- 仅指定单个文件,未遍历目录下所有文件
- 按空格分割字段的方式不可靠,会错误提取第二个参数
正确解决方案
方案1:用Grep处理(适用于参数与宏定义同行的场景)
如果所有CAKE_FROSTING的第一个参数都和CAKE_FROSTING(在同一行,可使用GNU Grep的PCRE特性:
grep -r -oP 'CAKE_FROSTING\(\s*"\K[^"]+' filesToCheck/ > result.txt
参数说明:
-r:递归遍历filesToCheck下所有文件-o:仅输出匹配到的内容-P:启用PCRE正则表达式CAKE_FROSTING\(\s*":匹配CAKE_FROSTING(及后续可能的空白字符、双引号\K:丢弃前面匹配的内容,只保留后续部分[^"]+:匹配双引号内的所有非引号字符(即第一个参数内容)
方案2:用Awk处理(支持跨行场景)
如果存在CAKE_FROSTING(和第一个参数跨行的情况(如file2.h),Awk的处理更可靠:
awk ' /CAKE_FROSTING\(/ { in_frosting = 1 } in_frosting { if (match($0, /"[^"]+"/)) { print substr($0, RSTART + 1, RLENGTH - 2) in_frosting = 0 } } ' filesToCheck/* > result.txt
逻辑说明:
- 当行中匹配到
CAKE_FROSTING(时,标记开始处理该宏 - 在标记状态下,查找行中的双引号字符串,提取并打印引号内的内容
- 提取完成后取消标记,避免重复处理
方案3:用Find+Sed处理(兼容更多系统)
若系统不支持Grep的-P参数,可结合Find和Sed实现:
find filesToCheck/ -type f -exec sed -n 's/.*CAKE_FROSTING(\s*"\([^"]*\)".*/\1/p' {} + > result.txt
参数说明:
find filesToCheck/ -type f:遍历目录下所有普通文件-exec sed ... {} +:对找到的文件批量执行Sed命令-n:默认不输出行内容s/.*CAKE_FROSTING(\s*"\([^"]*\)".*/\1/p:捕获第一个双引号内的内容并打印
内容的提问来源于stack exchange,提问作者JohnFreeman1212
相关产品推荐
相关产品推荐

