如何用sed递归替换目录下两模式间#include的引号为尖括号
解决方案
sed支持范围匹配语法,可指定仅在两个匹配模式之间执行替换操作,语法规则为:/起始匹配模式/,/结束匹配模式/ 替换操作。
1. 核心替换逻辑
将WINDOWS_DISABLE_WARNING到WINDOWS_ENABLE_WARNING区间内的引号包含的#include语句替换为尖括号格式,单个文件的测试命令如下:
sed '/WINDOWS_DISABLE_WARNING/,/WINDOWS_ENABLE_WARNING/ s/#include *"\([^"]*\)"/#include <\1>/g' 你的测试文件.cpp
正则说明:
- 用
\([^"]*\)捕获引号中间的头文件名,替换时用\1引用捕获的内容 - 末尾的
g表示单行内匹配到多个结果时全部替换(适配少数一行写多个include的极端情况)
2. 批量递归处理所有C/C++源文件
配合find过滤所有.cpp/.h/.hpp后缀的源文件,避免误改其他格式文件:
注意:以下为GNU sed(Linux环境默认)的写法,如果是macOS环境,需把
sed -i替换为sed -i ''
find ./ -type f \( -name "*.cpp" -o -name "*.h" -o -name "*.hpp" \) -exec sed -i '/WINDOWS_DISABLE_WARNING/,/WINDOWS_ENABLE_WARNING/ s/#include *"\([^"]*\)"/#include <\1>/g' {} \;
3. 一步到位删除冗余宏(可选)
如果需要直接删除两个宏定义得到最终的干净代码,可以扩展sed规则,一次性完成替换+删除操作:
find ./ -type f \( -name "*.cpp" -o -name "*.h" -o -name "*.hpp" \) -exec sed -i \ -e '/WINDOWS_DISABLE_WARNING/,/WINDOWS_ENABLE_WARNING/ s/#include *"\([^"]*\)"/#include <\1>/g' \ -e '/^ *WINDOWS_DISABLE_WARNING/d' \ -e '/^ *WINDOWS_ENABLE_WARNING/d' \ {} \;
注意事项
批量操作前建议先备份仓库代码,或者先对单个测试文件执行不带-i参数的sed命令,确认替换结果符合预期后再执行批量修改。
内容的提问来源于stack exchange,提问作者user3667089
相关产品推荐
相关产品推荐

