Nam Nguyen
Nam Nguyen

Reputation: 5750

add object to dynamic key using JQ

I'm looking to build object using jq and add object key to dynamic key and I could not figure out. Here is my sample script:

#!/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}"

actual outputs

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

But what I want is this

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

I could not figure out, please help!

Upvotes: 2

Views: 1297

Answers (1)

peak
peak

Reputation: 116640

The following script produces the desired result, and should be fairly robust:

#!/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'

The main point to note here is that in order to construct an object with a dynamically determined key, one has to use parentheses, as in {(KEY): VALUE}

Of course, if the values for the "environments" and "regions" were available in a more convenient form, the above could be simplified.

Output

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

Upvotes: 4

Related Questions