如何用jq根据子节点条件修改CycloneDX组件字段?
CycloneDX BOM 转换的完整jq实现方案
需求说明
将Syft生成的debian:bullseye-slim镜像CycloneDX格式JSON BOM按以下规则转换:
- 针对满足以下条件的组件:
purl以pkg:deb/debian/开头properties中包含syft:metadata:source属性
执行以下修改:
- 将
name替换为syft:metadata:source的属性值 - 若存在
syft:metadata:sourceVersion属性,将version替换为其属性值 - 重新生成
purl为pkg:deb/debian/{新name}@{新version}?arch=source
- 其他组件保持原有结构不变
原始JSON示例
{"bomFormat": "CycloneDX","components": [{"name": "bsdutils","version": "1:2.36.1-8+deb11u1","purl": "pkg:deb/debian/bsdutils@1:2.36.1-8+deb11u1?arch=amd64&upstream=util-linux%402.36.1-8+deb11u1&distro=debian-11","properties": [{"name": "syft:metadata:source","value": "util-linux"}, {"name": "syft:metadata:sourceVersion","value": "2.36.1-8+deb11u1"}]}, {"name": "curl","version": "7.74.0-1.3+deb11u7","purl": "pkg:deb/debian/curl@7.74.0-1.3+deb11u7?arch=amd64&distro=debian-11"}, {"name": "libaudit-common","version": "1:3.0-2","purl": "pkg:deb/debian/libaudit-common@1:3.0-2?arch=all&upstream=audit&distro=debian-11","properties": [{"name": "syft:metadata:source","value": "audit"}]}]}
目标JSON示例
{"bomFormat": "CycloneDX","components": [{"name": "util-linux","version": "2.36.1-8+deb11u1","purl": "pkg:deb/debian/util-linux@2.36.1-8+deb11u1?arch=source","properties": [{"name": "syft:metadata:source","value": "util-linux"}, {"name": "syft:metadata:sourceVersion","value": "2.36.1-8+deb11u1"}]}, {"name": "curl","version": "7.74.0-1.3+deb11u7","purl": "pkg:deb/debian/curl@7.74.0-1.3+deb11u7?arch=amd64&distro=debian-11"}, {"name": "audit","version": "1:3.0-2","purl": "pkg:deb/debian/audit@1:3.0-2?arch=source","properties": [{"name": "syft:metadata:source","value": "audit"}]}]}
完整jq转换脚本
.components |= map( if (.purl | startswith("pkg:deb/debian/")) and (.properties | any(.name == "syft:metadata:source")) then .props = (.properties | map({(.name): .value}) | add) | .name = .props["syft:metadata:source"] | (.props["syft:metadata:sourceVersion"] // empty) as $sourceVersion | if $sourceVersion then .version = $sourceVersion else . end | .purl = "pkg:deb/debian/\(.name)@\(.version)?arch=source" | del(.props) else . end )
脚本说明
- 使用
map遍历所有组件,通过条件判断筛选需要修改的目标组件 - 将
properties数组转换为键值对对象(临时字段.props),简化属性值的查找操作 - 按规则替换
name和version字段,其中version仅在sourceVersion存在时更新 - 生成符合要求的新
purl,最后删除临时字段.props保证结构整洁
使用方式
本地文件转换
将上述脚本保存为transform.jq,执行以下命令完成转换:
jq -f transform.jq original-bom.json > transformed-bom.json
流水线中直接处理
结合Syft生成BOM的命令,通过管道直接完成转换:
syft debian:bullseye-slim -o cyclonedx-json | jq -f transform.jq > final-bom.json
内容的提问来源于stack exchange,提问作者EricBDev
相关产品推荐
相关产品推荐

