使用JQ将对象添加到动态密钥

时间:2018-01-30 01:37:16

标签: json bash shell jq

我正在寻找使用jq构建对象并将对象键添加到动态键,我无法弄清楚。这是我的示例脚本:

#!/bin/bash -e

environments=('development' 'stage' 'production')
regions=('us-east-1' 'us-west-2')

tree='{}'

for environment in "${environments[@]}"
do
    echo "${environment}"
    # Or do something else with environment

    tree="$(jq --arg jqEnvironment "${environment}" '. | .[$jqEnvironment] = {}' <<< "${tree}")"

    for region in "${regions[@]}"
    do
        echo "${region}"
        # Or do something with region

        tree="$(jq --arg jqEnvironment "${environment}" --arg jqRegion "${region}" '. | .[$jqEnvironment] | .[$jqRegion] = {}' <<< "${tree}")"
    done
done

jq . <<< "${tree}"

实际产出

{
  "us-west-2": {}
}

但我想要的是这个

{
  "development": {
    "us-east-1": {},
    "us-west-2": {}
  },
  "stage": {
    "us-east-1": {},
    "us-west-2": {}
  },
  "production": {
    "us-east-1": {},
    "us-west-2": {}
  }
}

我想不通,请帮忙!

1 个答案:

答案 0 :(得分:3)

以下脚本会产生所需的结果,并且应该相当健壮:

#!/bin/bash

environments=('development' 'stage' 'production')
regions=('us-east-1' 'us-west-2')

jq -n --slurpfile e <(for e in "${environments[@]}" ; do echo "\"$e\""; done) \
   --slurpfile r <(for r in "${regions[@]}" ; do echo "\"$r\"" ; done) \
   '($r | map ({(.): {}}) | add) as $regions
     | [{($e[]): $regions}] | add'

这里要注意的要点是,为了使用动态确定的密钥构造对象,必须使用括号,如{(KEY): VALUE}

当然,如果“环境”和“地区”的值以更方便的形式提供,则可以简化上述内容。

输出

{
  "development": {
    "us-east-1": {},
    "us-west-2": {}
  },
  "stage": {
    "us-east-1": {},
    "us-west-2": {}
  },
  "production": {
    "us-east-1": {},
    "us-west-2": {}
  }
}