chrisst chrisst - 2 months ago 24
JSON Question

How to use jq to find all paths to a certain key

In a very large nested json structure I'm trying to find all of the paths that end in a key.

ex:

{
"A": {
"A1": {
"foo": {
"_": "_"
}
},
"A2": {
"_": "_"
}
},
"B": {
"B1": {}
},
"foo": {
"_": "_"
}
}


would print something along the lines of:
["A","A1","foo"], ["foo"]




Unfortunately I don't know at what level of nesting the keys will appear, so I haven't been able to figure it out with a simple select. I've gotten close with
jq '[paths] | .[] | select(contains(["foo"]))'
, but the output contains all the permutations of any tree that contains foo.
output:
["A", "A1", "foo"]["A", "A1", "foo", "_"]["foo"][ "foo", "_"]


Bonus points if I could keep the original data structure format but simply filter out all paths that don't contain the key (in this case the sub trees under "foo" wouldn't need to be hidden).

Answer

With your input: $ jq -c 'paths | select(.[-1] == "foo")' ["A","A1","foo"] ["foo"]

Bonus points:

$ jq 'reduce (tostream | select(length==2) | select(.[0] | index("foo"))) as $pair (null; setpath($pair[0]; $pair[1]))' { "A": { "A1": { "foo": { "_": "_" } } }, "foo": { "_": "_" } }