如何在bash中多次调用jq增量生成符合规范的JSON文档?
Bash + jq 生成JSON文档的最佳实践
分段构建合并JSON、支持嵌套结构的需求,可以通过以下几种成熟方案实现:
方案1:增量更新JSON对象(适合边收集数据边构建)
先初始化一个空JSON对象存在变量中,每次拿到新数据后调用jq合并字段,最终输出完整对象:
# 初始化空对象 json=$(jq -n '{}') # 收集foo字段并合并 read foo <<<$(</path/to/some/oneliner/file) json=$(jq --arg f "$foo" '. + {foo: $f}' <<< "$json") # 收集bar字段并合并 bar=$(some_command) json=$(jq --arg b "$bar" '. + {bar: $b}' <<< "$json") # 输出最终JSON echo "$json"
输出结果就是你需要的合并后对象:{"foo": "SOMETHING", "bar": "SOMETHING_ELSE"}
方案2:嵌套结构直接赋值
构建嵌套JSON不需要在bash里实现字典,直接用jq的路径赋值语法即可:
# 给嵌套的user.info.age字段赋值(数字类型用--argjson传递) json=$(jq --argjson age 28 '.user.info.age = $age' <<< "$json") # 合并嵌套子对象(深度合并用*运算符,避免覆盖已有子字段) address_obj=$(jq -n --arg city "Beijing" --arg street "Xueyuan Rd" '{city: $city, street: $street}') json=$(jq --argjson addr "$address_obj" '.user.info.address *= $addr' <<< "$json")
方案3:流式收集后一次性合并(适合字段多、不想多次调用jq的场景)
先把所有零散生成的单字段JSON对象按流式输出,最后用jq的-s参数批量合并:
# 收集所有零散JSON对象,最后一次性合并 { jq -n --arg f "$foo" '{foo: $f}' jq -n --arg b "$bar" '{bar: $b}' jq -n --argjson age 28 '{user: {info: {age: $age}}}' } | jq -s 'add'
核心注意事项
- 传递变量给jq时必须用双引号包裹,避免特殊字符、空格导致参数解析错误
- 非字符串类型(数字、布尔、null、子JSON对象)必须用
--argjson参数传递,避免被自动转为字符串类型 - 合并嵌套对象时如果要保留已有子字段,用
*深度合并运算符代替+或add浅合并
内容的提问来源于stack exchange,提问作者janneb
相关产品推荐
相关产品推荐

