You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash中通过循环结合jq生成嵌套JSON数据

在Bash中用jq动态生成Linode API格式的嵌套JSON

方法1:逐次循环构建(适合逐个获取变量的场景)

如果你的场景是在循环中逐个拿到device_name(如sda)、disk_id、volume_id变量,可以通过初始化空JSON结构,每次循环用jq更新结构来实现:

# 初始化基础JSON结构
json='{"devices": {}}'

# 模拟循环(实际场景替换成你的数据源,比如从文件/命令输出读取)
while read -r device_name disk_id volume_id; do
    # 处理disk_id:空值转为null,非空保留数字类型
    [[ -z "$disk_id" ]] && disk_val='null' || disk_val="$disk_id"
    # 处理volume_id同理
    [[ -z "$volume_id" ]] && volume_val='null' || volume_val="$volume_id"

    # 用jq更新devices对象,添加当前设备的配置
    json=$(echo "$json" | jq --arg dev "$device_name" \
                            --argjson did "$disk_val" \
                            --argjson vid "$volume_val" \
                            '.devices[$dev] = {"disk_id": $did, "volume_id": $vid}')
done <<EOF
sda 111 ""
sdb "" 444
sdc 222 ""
sdd 333 ""
EOF

# 输出最终JSON
echo "$json"

关键细节:

  • --arg:传递字符串类型的设备名(如sda)
  • --argjson:传递数字或null类型的ID,保证JSON类型正确(避免把数字转成字符串)
  • .devices[$dev] = ...:动态给devices对象添加键值对,支持新增或覆盖设备配置

方法2:批量构建(高效处理批量数据)

如果能一次性收集所有设备的配置数据,可以直接传给jq批量生成目标结构,无需循环,效率更高:

# 整理所有设备数据为JSON数组(实际场景可从命令输出/文件生成)
devices_data='[
  {"name": "sda", "disk_id": 111, "volume_id": null},
  {"name": "sdb", "disk_id": null, "volume_id": 444},
  {"name": "sdc", "disk_id": 222, "volume_id": null},
  {"name": "sdd", "disk_id": 333, "volume_id": null}
]'

# 用jq将数组转换为嵌套的devices结构
echo "$devices_data" | jq '{devices: (reduce .[] as $item ({}; .[$item.name] = {"disk_id": $item.disk_id, "volume_id": $item.volume_id}))}'

关键细节:

  • reduce .[] as $item ({}; ...):遍历数组中的每个设备项,逐步将空对象构建为目标devices结构
  • 这种方式避免了多次调用jq的开销,适合数据量较大的场景

为什么不用字符串拼接?

字符串拼接容易出现以下问题:

  • 手动处理null、引号等JSON语法细节,极易出错
  • 无法保证数据类型正确(比如把数字转成字符串,Linode API可能会拒绝)
  • 代码可读性差,维护成本高

内容的提问来源于stack exchange,提问作者Kalib Zen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:55:14