Annette
Annette

Reputation: 234

Update one value (matching a known key) in a list of JSON objects using jq

i have multiple json files in the below format as environment files and need to test it against an endpoint,

{
  "id": "test1123",
  "name": "my testing",
  "values": [
    {
      "enabled": true,
      "key": "URL",
      "value": "http://localhost:3000/",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "User1Token",
      "value": "",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "User2Token",
      "value": "",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "IdentityURL",
      "value": "",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "AdminToken",
      "value": "",
      "type": "text"
    }
  ],
  "timestamp": 1511892974802,
  "_postman_variable_scope": "environment",
  "_postman_exported_at": "2017-11-28T19:38:23.389Z",
  "_postman_exported_using": "Postman/5.3.0"
}

I wanted to update the end point in this json before running my test. The endpoint value needs to be added to value attribute of values object where the key is "URL"

so in the above case, i should update the endpoint in the first index of values array,

{
  "enabled": true,
  "key": "URL",
  "value": "http://10.20.200.1/",
  "type": "text"
}

where http://10.20.200.1/ is my endpoint.

The current code I'm trying to use is:

jq '.values | map(if .key == "URL" then . + {"value":"10.20.13.28/";} else . end )'

...but this results in a syntax error. Can anyone suggest me on how to use jq to update the value correctly?

Note: the key URL won't be always the first index of values.

Upvotes: 2

Views: 2027

Answers (2)

peak
peak

Reputation: 117017

The following is just a variation of @CharlesDuffy's excellent answer:

def when(c; f): if c? // null then f else . end;

.values = map( when(.key == $updateKey; .value = $updateVal) )

This definition of when/2 is quite generic. It adds a small measure of safety, and avoids the tedium of if _ then _ else . end. It is perhaps worthy of your standard jq library (e.g. ~/.jq or ~/.jq/jq/jq.jq).

Upvotes: 3

Charles Duffy
Charles Duffy

Reputation: 295914

If you want to keep other surrounding key/value pairs and only update the values item, you need to calculate a new value for it. Doing that may look like the following:

jq \
  --arg updateKey "URL" \
  --arg updateVal "http://10.20.200.1" \
  '.values = [.values[] | if (.key == $updateKey) then (.value = $updateVal) else . end]'

Upvotes: 8

Related Questions