如何为多行snprintf(log_buffer)语句的结尾分号后添加指定代码行?
批量处理多行snprintf语句的解决方案
核心思路
仅在识别到snprintf(log_buffer,...)起始行后,跟踪后续内容直到找到该语句的结尾分号,避免误匹配其他结构的分号(如struct option)。
方法一:使用awk处理单文件
awk的多行处理能力更适配这类场景:
awk ' /snprint.*log_buffer/ { in_snprintf = 1 } in_snprintf { buf = buf $0 ORS if (/;/) { sub(/;$/, ";\nsend_to_logger_process(log_buffer);", buf) printf "%s", buf buf = "" in_snprintf = 0 next } next } { print } ' input.c
- 工作逻辑:
- 匹配到
snprintf起始行时,标记进入处理状态 - 持续收集行内容到缓冲区,直到遇到结尾分号
- 替换结尾分号为
;\nsend_to_logger_process(log_buffer);后输出缓冲区 - 非目标行直接原样输出
- 匹配到
方法二:使用sed处理单文件
sed通过循环读取多行实现精准匹配:
:loop /snprint.*log_buffer/ { N /;/! b loop s/;/;\nsend_to_logger_process(log_buffer);/ } ' input.c
- 工作逻辑:
- 定义
loop标签,匹配起始行后读取下一行(N命令) - 如果当前内容不含分号,回到
loop继续读取 - 找到分号后执行替换,添加目标代码行
- 定义
批量处理目录下所有文件
结合find命令批量处理指定类型文件(以.c为例),同时保留备份:
awk批量处理
find . -type f -name "*.c" -exec awk ' /snprint.*log_buffer/ { in_snprintf = 1 } in_snprintf { buf = buf $0 ORS if (/;/) { sub(/;$/, ";\nsend_to_logger_process(log_buffer);", buf) printf "%s", buf buf = "" in_snprintf = 0 next } next } { print } ' {} > {}.tmp && mv {}.tmp {} \;
sed批量处理(自动生成.bak备份)
find . -type f -name "*.c" -exec sed -i.bak ':loop /snprint.*log_buffer/ { N /;/! b loop s/;/;\nsend_to_logger_process(log_buffer);/ } ' {} \;
- 处理完成后,可执行
find . -name "*.bak" -delete删除备份文件
内容的提问来源于stack exchange,提问作者Jonathan Leslie
相关产品推荐
相关产品推荐

