如何用jq 1.5将环境变量转为指定键值结构的JSON对象
解决jq 1.5从环境变量生成键值对JSON对象的问题
我来帮你搞定这个问题!你当前的命令之所以得到不符合预期的结果,是因为{$regions}是jq的对象简写语法,它会直接把变量名regions作为键,变量值作为对应的值,而不是把$regions里的内容拆分成多个键。
要实现把REGIONS的每个元素作为键、KMS_KEYS对应位置的元素作为值,需要先把两个环境变量的字符串分割成数组,再遍历数组构建键值对对象,具体步骤如下:
正确的jq命令
jq --arg regions "$REGIONS" --arg kmskeys "$KMS_KEYS" ' .builders[].region_kms_key_ids = ( # 将两个环境变量字符串按逗号分割为数组 $regions | split(",") as $region_list | $kmskeys | split(",") as $key_list # 遍历数组索引,构建键值对对象 | reduce range(0; $region_list | length) as $i ({}; .[$region_list[$i]] = $key_list[$i]) ) ' test.json
命令详解
- 分割字符串为数组:用
split(",")把$regions和$kmskeys这两个逗号分隔的字符串转成数组,比如$regions会变成["region1", "region2"],$kmskeys变成["key1", "key2"]。 - 构建键值对对象:用
reduce遍历数组的索引,初始值是一个空对象{},每次循环把当前索引对应的region作为键,对应的kms key作为值添加到对象中。 - 赋值到目标字段:把最终生成的键值对对象赋值给
.builders[]里的region_kms_key_ids字段。
测试结果
执行这个命令后,你会得到期望的输出:
{ "builders": [ { "name": "aws", "region_kms_key_ids": { "region1": "key1", "region2": "key2" } } ] }
可选简洁写法(jq 1.5+支持)
如果你的jq版本支持transpose(等同于zip)函数,也可以用更简洁的方式实现:
jq --arg regions "$REGIONS" --arg kmskeys "$KMS_KEYS" ' .builders[].region_kms_key_ids = ( [$regions|split(","), $kmskeys|split(",")] | transpose | map({key: .[0], value: .[1]}) | from_entries ) ' test.json
这里用transpose把两个数组配对成[["region1","key1"], ["region2","key2"]],再转成{key, value}格式的数组,最后用from_entries生成目标对象。
内容的提问来源于stack exchange,提问作者jaxim
相关产品推荐
相关产品推荐

