fusio
fusio

Reputation: 3675

Modify JSON values based on array of keys using jq

I need to change the value of a set of keys (defined in a variable) in a JSON object using jq.

As example, I have this JSON object:

{
    foo: {
        bar: 1,
        baz: 2,
        qux: 3
    }
}

and the following variable:

update_keys = ["bar", "baz"]

I would like to say 'change the value of the keys in update_keys to X'.

The following works:

.foo = (.foo | 
        to_entries | 
        map(if .key == "bar" or .key == "baz" 
        then . + { "value":"X" } 
        else . 
        end) |
        from_entries)

But instead of if .key == "bar" or .key == "baz" I am looking for a way to say if .key in update_keys, or a similar logic.

Upvotes: 2

Views: 3361

Answers (3)

jq170727
jq170727

Reputation: 14635

In this problem since $update_keys is just an array all that is needed is

 .foo[ $update_keys[] ] = "X"

e.g. if

  ["bar","baz"] as $update_keys
| .foo[ $update_keys[] ] = "X"

is in filter.jq and data.json contains the (slighty corrected) data

{
  "foo": {
    "bar": 1,
    "baz": 2,
    "qux": 3
  }
}

then

jq -M -f filter.jq data.json

produces

{
  "foo": {
    "bar": "X",
    "baz": "X",
    "qux": 3
  }
}

If you want to pass in the value for update keys instead of defining it in your script you can easily use --argjson as peak's answer shows.

Upvotes: 0

peak
peak

Reputation: 116680

Here's a slightly different approach using --argjson to parameterize update_keys, and index/1:

$ cat update.jq
.foo |= with_entries( . as $in 
          | if $update_keys | index($in.key) then .value = "X" else empty end)

$ update_keys='["bar", "baz"]'

$ jq --argjson update_keys "$update_keys" -f update.jq input.json

Output:

{
  "foo": {
    "bar": "X",
    "baz": "X"
  }
}

Upvotes: 0

unconditional
unconditional

Reputation: 7656

Here you go.

Filter

.foo |= with_entries( .value = if ([.key] | inside(["bar", "baz"])) then "X" else .value end )

Input

{
    "foo": {
        "bar": 1,
        "baz": 2,
        "qux": 3
    }
}

Output

{
  "foo": {
    "bar": "X",
    "baz": "X",
    "qux": 3
  }
}

Check out the cookbook for more recipies and techniques of jq usage:
https://github.com/stedolan/jq/wiki/Cookbook

Upvotes: 1

Related Questions