Monday, October 10, 2022

[SOLVED] How to generate all JSON paths conditionally with jq

Issue

I have arbitrarily nested JSON objects similar to below.

{
  "parent1" : "someval"
  "parent2" : {
     "a" : "someval",
     "b" : "someval"
   }
  "parent3" : {
     "child1" : { 
        "a" : "someval"
      },
     "child2" : { 
        "b" : "someval"
      }
   }
}

I need to recursively go through them and check to see if any parent has children keys a or b, or both, and generate the JSON path to that parent like so:

Output:
parent2 
parent3.child1
parent3.child2

I have tried using

jq -r 'path(..) | map (. | tostring) | join (".")

which helps me generate all paths, but haven't found a way to combine conditions like has("a") with path successfully. How can I go about achieving this ?


Solution

You could use index to check if you keys are in the path array:

path(..) | select(index("a") or index("b")) | join(".")
"parent2.a"
"parent2.b"
"parent3.child1.a"
"parent3.child2.b"

JqPlay demo


If you don't want the last key, you could add [:-1] to 'remove' the last index in each array to output:

path(..) | select(index("a") or index("b"))[:-1] | join(".")
"parent2"
"parent2"
"parent3.child1"
"parent3.child2"

JqPlay demo



Answered By - 0stone0
Answer Checked By - Candace Johnson (WPSolving Volunteer)