如何用JQ遍历Bash数组并更新指定JSON数组?
用JQ批量更新JSON数组的简洁方案
需求场景
现有Bash数组fruit_array=("banana" "orange"),需要将原始JSON中foods.perishable.fruit的空数组,替换为每个元素对应{"001": {"002": "元素值"}}结构的数组。此前尝试循环更新时每次都会重新读取模板文件,仅能完成单次更新;使用--argjson传递数组时出现无法处理的转义字符串问题。
解决方案
方法1:分步生成JSON数组并更新
先将Bash数组转换为合法的JSON数组,再通过--argjson传递给JQ,最后映射为目标结构:
- 将Bash数组转为JSON数组:
json_fruits=$(printf '%s\n' "${fruit_array[@]}" | jq -R . | jq -s .)
printf '%s\n' "${fruit_array[@]}":逐行输出数组元素jq -R .:将每行内容转为JSON字符串格式jq -s .:将所有JSON字符串合并为一个JSON数组
- 用JQ更新原始JSON文件:
jq --argjson fruits "$json_fruits" '.foods.perishable.fruit = $fruits | map({ "001": { "002": . } })' input.json
--argjson fruits "$json_fruits":将生成的JSON数组传递给JQ,命名为$fruits.foods.perishable.fruit = $fruits:替换目标路径的数组map({ "001": { "002": . } }):将数组中每个元素映射为需要的嵌套对象结构
方法2:单命令链式处理
将数组转换、结构映射、JSON更新合并为一条命令,更简洁:
printf '%s\n' "${fruit_array[@]}" | jq -R '{ "001": { "002": . } }' | jq -s '.' | jq --argjson new_fruits - '.foods.perishable.fruit = $new_fruits' input.json
- 第一个
jq -R '{ "001": { "002": . } }':直接将每个数组元素转为目标对象 jq -s '.':将所有对象合并为一个数组jq --argjson new_fruits -:从标准输入读取生成的数组,赋值给$new_fruits,再替换到JSON目标路径
示例效果
原始input.json内容:
{ "foods": { "perishable": { "fruit": [] } } }
运行命令后输出:
{ "foods": { "perishable": { "fruit": [ { "001": { "002": "banana" } }, { "001": { "002": "orange" } } ] } } }
原地修改文件
如果需要直接修改源文件,添加-i选项(in-place编辑):
printf '%s\n' "${fruit_array[@]}" | jq -R '{ "001": { "002": . } }' | jq -s '.' | jq --argjson new_fruits - '.foods.perishable.fruit = $new_fruits' -i input.json
内容的提问来源于stack exchange,提问作者extra_peppermint
相关产品推荐
相关产品推荐

