skip to Main Content

Given test file: sample.json:

{
  "host_config": {
    "host1.reg.fqdn.com": {
      "config1": "AAA",
      "config2": "000"
},
    "host2.reg.fqdn.com": {
      "config1": "BBB",
      "config2": "000"
},
    "host3.reg.fqdn.com": {
      "config1": "CCC",
      "config2": "000"
     }
  }
}

I need to update "config2" for each of the hostname keys but i cannot seem to get the correct jq syntax using the –arg var definition format for the hostnames. (using jq1.6)

jq '.host_config."host1.reg.fqdn.com".config2=1' sample.json                 good!
jq --arg a "1" '.host_config."host1.reg.fqdn.com".config2=$a' sample.json    good!
jq --arg a "1" --arg b "host1.reg.fqdn.com" '.host_config."$b".config2=$a' sample.json  
completes but does not sub in "host1.reg.fqdn.com" for b - it creates new key under .host_config like:  
  "$b": {
    "config2": "1"
  }
jq --arg a "1" --arg b "host1.reg.fqdn.com" '.host_config.'$b'.config2=$a' sample.json  => jq error
jq --arg a "1" --arg b "host1.reg.fqdn.com" '.host_config.[$b].config2=$a' sample.json  => jq error
jq --arg a "1" --arg b "host1.reg.fqdn.com" '.host_config.['$b'].config2=$a' sample.json  => jq error
jq --arg a "1" --arg b "host1.reg.fqdn.com" '.host_config.["$b"].config2=$a' sample.json  => jq error
jq --arg a "1" --arg b "host1.reg.fqdn.com" '.host_config.'"$b"'.config2=$a' sample.json => jq error
jq --arg a "1" --arg b "host1.reg.fqdn.com" '.host_config."'$b'".config2=$a' sample.json => completes but
creates:
  "": {
    "config2": "1"
  }

Ultimately what I want to do is something like:

for i in 1..3 ; do
   jq --arg a "$i" --arg b "host${i}.reg.fqdn.com" '.host_config."$b".config2=$a' sample.json
done

2

Answers


  1. .host_config."$b".config2
    

    contains the literal key $b and will not be interpolated, the same way that "$a" is a string literal containing a dollar and the letter ‘a’. To get the key name from the variable value, use the brackets:

    .host_config[$b].config2
    
    Login or Signup to reply.
  2. Here is the correct way to achieve the update of the config2 values dynamically based on the hostname using a for loop in bash with the right jq syntax:

    for i in 1 2 3; do
       host="host${i}.reg.fqdn.com"
       jq --arg a "$i" --arg b "$host" '.host_config[$b].config2 = $a' sample.json > temp.json && mv temp.json sample.json
    done
    

    Explanation:

    --arg a "$i": This sets the variable a to the value of $i (which in your loop goes from 1 to 3).

    --arg b "$host": This sets the variable b to the hostname string like host1.reg.fqdn.com.

    .host_config[$b].config2 = $a: This uses the value of $b to dynamically access the correct host object in host_config and sets its config2 property to the value of $a.
    The changes are written to temp.json to ensure that each command execution works on an updated file. After running the command, temp.json is moved to overwrite sample.json, effectively saving the changes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search