如何让jq在capture匹配失败时仍输出所有输入元素?
解决DTrack接口依赖提取问题:保留所有元素,仅输出匹配成功的字段
核心思路
- 先解析
directDependencies字段中的转义JSON字符串,将其转换为可操作的JSON数组 - 遍历每个依赖字符串,尝试匹配目标依赖格式;匹配失败时不添加对应字段,而非过滤掉整个元素
具体JQ脚本示例
假设接口返回的顶层数据是包含项目对象的数组,每个项目包含directDependencies转义JSON字段,使用以下脚本处理:
map( .directDependencies = (.directDependencies | fromjson | map( . as $depStr | # 逐个匹配目标依赖,失败则用空对象替代(不生成对应字段) (capture("com.example.commons/dep1@(?<dep1>[^@]+)") // {}) + (capture("com.example.commons/dep2@(?<dep2>[^@]+)") // {}) + (capture("com.example.commons/dep3@(?<dep3>[^@]+)") // {}) + (capture("com.example.commons/dep4@(?<dep4>[^@]+)") // {}) )) )
脚本说明
fromjson:将directDependencies中的转义JSON字符串解析为原生JSON数组,方便后续操作map():遍历数组中的每个依赖字符串,确保所有输入元素都被处理并保留capture(...) // {}:尝试匹配指定格式的依赖版本,若匹配失败(返回null),则用空对象替代,避免添加不存在的字段- 对象合并(
+):将四个匹配结果合并为一个对象,仅包含匹配成功的dep1/dep2/dep3/dep4字段
简化场景(仅处理依赖数组)
如果只需要处理directDependencies解析后的数组,可使用更简洁的版本:
.directDependencies | fromjson | map( . as $depStr | (capture("com.example.commons/dep1@(?<dep1>[^@]+)") // {}) + (capture("com.example.commons/dep2@(?<dep2>[^@]+)") // {}) + (capture("com.example.commons/dep3@(?<dep3>[^@]+)") // {}) + (capture("com.example.commons/dep4@(?<dep4>[^@]+)") // {}) )
自定义调整
若依赖的groupId或格式有变化,只需修改capture中的正则表达式即可。例如,匹配任意groupId的依赖:
capture("[^/]+/dep1@(?<dep1>[^@]+)") // {}
内容的提问来源于stack exchange,提问作者crizzis
相关产品推荐
相关产品推荐

