Home > Back-end >  jq doesn't inject value into the json file
jq doesn't inject value into the json file

Time:01-25

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.

  •  Tags:  
  • Related