[英]Build nested json data from variable with looping with jq using bash
我正在尝试使用jq创建一个动态的json数据,但我不知道在涉及循环时如何编写它。 我可以在普通的 bash 中写一个序列字符串来做到这一点
这是示例代码:
#!/bin/bash
# Here I declare 2 arrays just to demonstrate. Each values pairs between `disk_ids` and `volume_ids` cannot have the same value. If one has value, the other must null.
disk_ids=(111 null 222 333)
volume_ids=(null 444 null null)
json_query_data=""
# Now example I want to loop through the above 2 arrays and create json. In real application I already have the above arrays that is looping where I can access using $disk_id and $volume_id.
for disk_id in "${disk_ids[@]}"; do
for volume_id in "${volume_ids[@]}"; do
json_query_data=$(jq -n --argjson disk_id "$disk_id" --argjson volume_id "$volume_id" '{
devices: {
sda: {"disk_id": $disk_id, "volume_id": $volume_id },
sdb: {"disk_id": $disk_id, "volume_id": $volume_id },
sdc: {"disk_id": $disk_id, "volume_id": $volume_id },
sdd: {"disk_id": $disk_id, "volume_id": $volume_id },
}}')
done
done
如您所见,这绝对不是我想要的输出,而且我的代码编写逻辑也不是动态的。 当我echo "${json_query_data}"
时,最终输出应该产生以下 json:
{
devices: {
sda: {"disk_id": 111, "volume_id": null },
sdb: {"disk_id": null, "volume_id": 444 },
sdc: {"disk_id": 222, "volume_id": null },
sdd: {"disk_id": 333, "volume_id": null },
}}
在使用jq
创建 json 数据时,我还没有在网上看到任何关于使用变量循环的示例。 感谢有人可以提供帮助。 谢谢。
更新:
我必须在 bash 中使用 for 循环来创建 json 数据。 因为我在代码中提供的示例数组disk_ids
和volume_ids
只是示例,在实际应用程序中我已经能够访问每个 for 循环计数器的变量$disk_id
和$volume_id
。 但是我如何使用这个变量并创建 json 输出来填充 for 循环中上面的所有数据?
json示例取自: linode API here
循环/映射也可以在 jq 中完成:
#!/bin/bash
disk_ids=(111 null 222 333)
volume_ids=(null 444 null null)
jq -n --arg disk_ids "${disk_ids[*]}" --arg volume_ids "${volume_ids[*]}" '
[$disk_ids, $volume_ids | . / " " | map(fromjson)]
| transpose | {devices: with_entries(
.key |= "sd\([. + 97] | implode)"
| .value |= {disk_id: first, volume_id: last}
)}
'
或者,如果您已经可以用相同的方式提供字母:
#!/bin/bash
disk_ids=(111 null 222 333)
volume_ids=(null 444 null null)
letters=(a b c d)
jq -n --arg disk_ids "${disk_ids[*]}" --arg volume_ids "${volume_ids[*]}" --arg letters "${letters[*]}" '
[$disk_ids, $letters, $volume_ids | . / " " ] | .[0,2] |= map(fromjson)
| transpose | {devices: with_entries(
.key = "sd\(.value[1])"
| .value |= {disk_id: first, volume_id: last}
)}
'
输出:
{
"devices": {
"sda": {
"disk_id": 111,
"volume_id": null
},
"sdb": {
"disk_id": null,
"volume_id": 444
},
"sdc": {
"disk_id": 222,
"volume_id": null
},
"sdd": {
"disk_id": 333,
"volume_id": null
}
}
}
更新:
我必须在 bash 中使用 for 循环来创建 json 数据。
如果您坚持在 bash 循环中执行此操作,那么:
#!/bin/bash
disk_ids=(111 null 222 333)
volume_ids=(null 444 null null)
json='{"devices": {}}'
for i in ${!disk_ids[@]}
do
json="$(
jq --argjson disk_id "${disk_ids[$i]}" --argjson volume_id "${volume_ids[$i]}" '
.devices |= . + {"sd\([length + 97] | implode)": {$disk_id, $volume_id}}
' <<< "$json"
)"
done
echo "$json"
或者,包含字母:
#!/bin/bash
disk_ids=(111 null 222 333)
volume_ids=(null 444 null null)
letters=(a b c d)
json='{"devices": {}}'
for i in ${!disk_ids[@]}
do
json="$(
jq --argjson disk_id "${disk_ids[$i]}" --argjson volume_id "${volume_ids[$i]}" --arg letter "${letters[$i]}" '
.devices["sd\($letter)"] += {$disk_id, $volume_id}
' <<< "$json"
)"
done
echo "$json"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.