PeterVandivier
Is there a flag or shell one-liner I can use to enumerate all valid leaf-node json paths in a document?
For example, given the following `document.json`...
```json
{
"a": "foo",
"b": [
1,
2,
{
"d": "bar",
"e": [
0
]
}
],
"f": {
"g": "baz"
},
"h": null,
"i": "zap"
}
```
...I would like a command to return the following...
```sh
# js ./document.json --get-leaf-paths
.a
.b[0]
.b[1]
.b[2].d
.b[2].e[0]
.f.g
.h
.i
```
For reference, I've spent the morning nearly getting this to work in powershell with [this function (link)][1], but I'm wondering if I'm either missing something built in to jq in it's [voluminous man page][2] or if there's an easy bash one-liner I'm too dense to see.
[1]: https://floobits.com/PoshCode/PowerShell.Slack.com/file/petervandivier/Get-PropertyValues.ps1:138
[2]: https://stedolan.github.io/jq/manual/
Top Answer
Jack Douglas
you can use `paths(scalars)` (or `leaf_paths`, but that is deprecated according to the `man` page).
To convert the path arrays produced by `paths(scalars)` to the readable text representation I used a custom function `pathexpr` I found [in the jq issue tracker](https://github.com/stedolan/jq/issues/1949) on GitHub.
```
echo '{ "a": "foo", "b": [ 1, 2, { "d": "bar", "e": [1] } ], "f": { "g": "baz" }, "h": null, "i": "zap" }' | \
jq 'paths(.==null or scalars) | map(if type == "number" then "[\(tostring)]" else "."+. end) | join("")'
".a"
".b[0]"
".b[1]"
".b[2].d"
".b[2].e[0]"
".f.g"
".h"
".i"
```
[Try it online!](https://tio.run/##JYsxDoMwEAT7vGJ1DaAgJFJG4iVAYYPBILCJbYqQ8HZyVrqdmzkpvL4u1WmL5AMS9AQN1lIOkrxrlDkeOVj1UUnholJRlS1OtEwDEwfjPzgIJx81k9mXhecUxSE2Fgm@aG7zC8kmgvZpUVUxgnXwnViE8xkXq9jSaUB4bwpVBTL7KpUjBK0MqG7SYH1wkxmzlqAWr0AF3Qso08f32U4mJcqS6/oB "Bash – Try It Online")
Note that if you have `null` values, `jq` version 1.5 (like the version in TIO) will not return those keys in the output above, but 1.6 works as intended.