Search code examples
jsonselectkeyjq

jq select where property contains property by name


I have a basic JSON structure:

{
  "A": {
    "Option1": {
      "contains": {
         "inner1": { ... },
         "inner2": { ... },
         "innerN": { ... }
      }
    }

    "Option2": {
         "innerX": { ... },
         "innerY": { ... },
         "innerZ": { ... }
    }
  }
}

What I need is to select either Option1 or Option2 based on whether or not it contains user input.

For example:

  • If the user provides inner1, return the Option1 object
  • If the user provides innerY return the Option2 object
  • etc.

I have been successful if the options were an array, but I cannot do this if they are objects themselves.

I tried looking at this example using descend but didn't quite follow.


Update 1

I got a sloppy means to do this and then reuse the expression:

jq -r 'paths | select(.[-1] == "inner1") | .[0:-2] | join(".")' myFile.json

I can store that in a variable and reuse it. But that seems sloppy. It's a workaround, though.

To test that out I did this:

jq .$(THAT_COMMAND_ABOVE) myFile.json

Solution

  • Using your approach, the jq filter you'd need is getpath:

    getpath(paths | select(.[-1] == "inner1") | .[0:-2])
    

    As an alternative, you could also use .., e.g. perhaps:

    .. | objects | map_values( select(has("inner1"))) | select(length>0)