I have json file env.json having following content:
{
"parameters": {
"name": "www",
"dev" : "",
"prod": ""
}
}
Now I want to inject values of dev and prod via a bash script using jq. Here's the code:
ENVJSON=$(cat env.json)
jq '.parameters.name = $val' --arg val $NAME <<<"$ENVJSON" > env.json
jq '.parameters.prod = $val' --arg val $PROD <<<"$ENVJSON" > env.json
jq '.parameters.dev = $val' --arg val $DEV <<<"$ENVJSON" > env.json
When I run this, I get the values of $NAME and $DEV correctly injected into the JSON file. But the $PROD value doesn't get injected for the prod index. It stays empty. Looks like this is an issue with the middle line.
If I swap the last two lines, then yes, the middle line doesn't work.
What could be wrong here?
I also tried appending && sleep 1 at end of each jq command, no luck.
CodePudding user response:
You could do a multi-value replacement with jq to prevent overwriting the same file again and again.
#!/usr/bin/bash
NAME=name
DEV=dev
PROD=prod
echo -e "$(jq --arg name $NAME --arg dev $DEV --arg prod $PROD '.parameters.name = ($name) | .parameters.dev = ($dev) | .parameters.prod = ($prod)' env.json)" > env.json
CodePudding user response:
It is not needed to read the JSON template from a file if it never changes. The template is incorporated in the jq filter script that takes a --null-input or -n, so it can directly be written to the output file, without saving to an intermediate temporary file.
NAME='www foo' PROD='prod bar thing' DEV='stuff for dev baz'
jq -n --arg name "$NAME" --arg prod "$PROD" --arg dev "$DEV" \
'{"parameters":{"name":$name,"dev":$dev,"prod":$prod}}' > env.json
cat env.json:
{
"parameters": {
"name": "www foo",
"dev": "stuff for dev baz",
"prod": "prod bar thing"
}
}
CodePudding user response:
Other answers are great, but I made a dumb mistake which I want to point out. In these commands,
ENVJSON=$(cat env.json)
jq '.parameters.name = $val' --arg val $NAME <<<"$ENVJSON" > env.json
jq '.parameters.prod = $val' --arg val $PROD <<<"$ENVJSON" > env.json
jq '.parameters.dev = $val' --arg val $DEV <<<"$ENVJSON" > env.json
I was using the same input in each of these commands, not the updated one. So I changed it to:
jq '.parameters.name = $val' --arg val $NAME <<<"$(cat env.json)" > env.json
jq '.parameters.prod = $val' --arg val $PROD <<<"$(cat env.json)" > env.json
jq '.parameters.dev = $val' --arg val $DEV <<<"$(cat env.json)" > env.json
and it worked.
