如何用sed正确提取编译器警告中的文件路径、行号等信息?
编译器警告日志提取格式修正
问题场景
我需要从release-log.txt文件中提取文件路径、行号、编译器警告编号(如C6001、C6011、C28197)以及警告消息,但当前使用的sed命令输出不符合预期。
当前执行的命令:
grep -E "C6001|C6011|C28197" release-log.txt | head | sed -r 's/^([a-zA-Z\\:.]+)\(([0-9]+)\) warning (C[0-9]+): (.+).(.+)$/(\3) \1:\2 \4/g'
部分警告日志示例:
C:\WindowsFabric\src\prod\ktl\src\inc\kallocator.h(196): warning C6011: Dereferencing NULL pointer 'Allocator'. : Lines: 189, 196 [C:\WindowsFabric\src\prod\src\Lease\KTransport\user\KTransport.user.vcxproj] C:\WindowsFabric\src\prod\ktl\src\inc\kstringview.proto.h(2505): warning C6001: Using uninitialized memory '*Temp_value_#2479'.: Lines: 2493, 2492, 2496, 2505, 2506, 2505 [C:\WindowsFabric\src\prod\src\Lease\KTransport\user\KTransport.user.vcxproj]
期望输出格式(以第一条日志为例):
(C6011) C:\WindowsFabric\src\prod\ktl\src\inc\kallocator.h:196 Dereferencing NULL pointer 'Allocator'
原命令问题分析
- 路径匹配不完整:原正则里的
[a-zA-Z\\:.]+只覆盖了字母、反斜杠、冒号和点,但Windows路径包含数字、下划线、正斜杠等字符,导致路径匹配失败或不完整。 - 消息匹配逻辑错误:原表达式用
.+.(.+)$拆分消息,会把警告消息末尾的句号和后续的: Lines:...内容错误分割,导致提取的消息带多余字符或缺失部分内容。
修正后的命令
grep -E "C6001|C6011|C28197" release-log.txt | head | sed -r 's/^([a-zA-Z0-9\\:_/.]+)\(([0-9]+)\): warning (C[0-9]+): (.+)\. : Lines:.*/(\3) \1:\2 \4/g'
修正点说明
- 路径匹配优化:将路径匹配正则改为
[a-zA-Z0-9\\:_/.]+,覆盖Windows路径中所有可能的字符,确保完整提取文件路径。 - 消息匹配精准化:用
(.+)\. : Lines:匹配到警告消息末尾的句号加空格位置,直接丢弃后面的: Lines:...及之后的内容,保证提取的消息干净准确。 - 输出格式对齐:替换后的结果严格对应期望格式,将警告编号用括号包裹,路径和行号用冒号连接,最后是纯净的警告消息。
测试效果
用第一条日志测试,输出完全符合预期:
(C6011) C:\WindowsFabric\src\prod\ktl\src\inc\kallocator.h:196 Dereferencing NULL pointer 'Allocator'
内容的提问来源于stack exchange,提问作者Node.JS
相关产品推荐
相关产品推荐

