dbarnett
dbarnett

Reputation: 85

Modifying nested json conditionally using jq

I would like to modify something like the following JSON:

{
  "foobar": {
    "a": {
      "adkjfe": {
        "A": 1,
        "foo": "bar"
      }
    },
    "b": {
      "ekjaei": {
        "A": 2,
        "bar": "foo"
      }
    }
  }
}

to add more data say {"baz": ["bing", "bop"]} to the parent of A if A=1. Assuming I don't know the parent key while leaving the rest of the json untouched. I've tried many different things including:

.foobar | .. | .. | .[] | if select(.A==1) then . += {"baz": "bing"} else . end 

which gives me an error and only my modified section.

The result, in this case, that I would like to see is:

{
  "foobar": {
    "a": {
      "adkjfe": {
        "A": 1,
        "foo": "bar",
        "baz": ["bing", "bop"]
      }
    },
    "b": {
      "ekjaei": {
        "A": 2,
        "bar": "foo"
      }
    }
  }
}

Upvotes: 5

Views: 421

Answers (2)

peak
peak

Reputation: 116670

In general it is better to avoid .. if possible, for reasons of efficiency. In the present case, the following will do the job:

(.foobar[][] | select(.A == 1)) |= .+ {"baz":["bing", "bop"]}

Upvotes: 4

Bertrand Martel
Bertrand Martel

Reputation: 45352

Select only fields that are of type object and that match your condition (A == 1) :

jq '(.foobar | .. | select(type == "object" and .A == 1)) |= .+ {"baz": ["bing", "bop"]}' test.json

The () around the filter query take care that the whole document will be returned with the updated fields and not just your subdocument

Upvotes: 5

Related Questions