Reputation: 5750
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
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.
{
"development": {
"us-east-1": {},
"us-west-2": {}
},
"stage": {
"us-east-1": {},
"us-west-2": {}
},
"production": {
"us-east-1": {},
"us-west-2": {}
}
}
Upvotes: 4