5

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

2 Answers 2

5

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

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

2 Comments

Works like buttah! Thank you!
it seems also possible to use | objects in place of type == "object" since jq 1.4 which may be more readable.
4

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

1 Comment

This works because each [] essentially moves down one object tree level, so this solution searches at a fixed 2-levels deep. (This has been a conceptual problem for me since my mind is conditioned to think 'array' when it sees []). And it's more efficient because the .. literally iterates every node right out to the leaf, which may be unnecessary, though probably unavoidable if the structure is more ragged.

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.