如何使用input为jq处理composer.lock生成的JSON填充uuidgen生成的UUID值
给composer.lock提取的JSON对象新增UUID字段的实现方案
jq本身无法直接在内部调用外部的uuidgen命令为每个对象生成独立UUID,可通过以下两种方案实现需求:
方案1:逐行处理(适合包数量较少的场景)
< composer.lock jq -c '.packages[] | {site: "foo", name: .name, version: .version, type: .type}' | while read -r line; do jq --arg uuid "$(uuidgen)" '. + {uuid: $uuid}' <<< "$line" done | jq -s
说明:
- 给第一个jq命令加
-c参数,将每个包的JSON对象压缩为单行输出,方便逐行读取 - 用while循环逐行读取每个包对象,每次循环调用
uuidgen生成全新的UUID - 通过
--arg参数将生成的UUID传入jq,用. + {uuid: $uuid}语法将UUID字段合并到原有对象中 - 最后仍用
jq -s将所有处理后的对象合并为数组,和原有输出格式完全兼容
方案2:批量合并(适合包数量较多的场景,性能更高)
# 先统计包的总数量 pkg_count=$(< composer.lock jq '.packages | length') # 生成对应数量的UUID数组 uuids=$(for i in $(seq 1 $pkg_count); do uuidgen; done | jq -R . | jq -s .) # 一次性将UUID和包信息合并输出 < composer.lock jq --argjson uuids "$uuids" '.packages | to_entries | map({site: "foo", name: .value.name, version: .value.version, type: .value.type, uuid: $uuids[.key]})'
说明:
- 该方案仅调用3次jq命令,相比逐行处理少调用N-1次jq(N为包数量),处理几百上千个包时效率优势明显
- 无需管道循环,输出结果直接是合并好的数组,不需要最后再加
jq -s处理
内容的提问来源于stack exchange,提问作者Mikke Schirén
相关产品推荐
相关产品推荐

