2

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.

5
  • Could you elaborate on what the outcome should be. Not sure if you want to extend update_keys or modify .foo Commented Mar 22, 2016 at 8:57
  • I want to update foo, changing the values of the keys defined in the update_keys array (all keys change to the same value) Commented Mar 22, 2016 at 9:06
  • Is update_keys already a variable that you've defined in jq? Commented Mar 22, 2016 at 9:11
  • @TomFenech no, I am very new to jq.. did not know we could have variables Commented Mar 22, 2016 at 9:21
  • Never knew of this tool. Thanks a buch for pointing it out! Commented Mar 22, 2016 at 12:48

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

Comments

0

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"
  }
}

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.