假设我们有以下JSON:
[
{
"dir-1": [
"file-1.1",
"file-1.2"
]
},
"dir-1",
{
"dir-2": [
"file-2.1"
]
}
]我们想要得到下一个输出:
"dir-1/file-1.1"
"dir-1/file-1.2"
"dir-1"
"dir-2/file-2.1"即,获取到所有leafs的路径,将项目与/连接起来。有没有办法在JQ上做到这一点?
我试过这样的方法:
cat source-file | jq 'path(..) | [ .[] | tostring ] | join("/")'但它不会产生我所需要的东西。
发布于 2017-10-29 20:43:02
您可以通过将路径与其值合并来利用流的工作方式。流只对叶值发出path, value对。忽略编号的索引。
$ jq --stream '
select(length == 2) | [(.[0][] | select(strings)), .[1]] | join("/")
' source-file返回:
"dir-1/file-1.1"
"dir-1/file-1.2"
"dir-1"
"dir-2/file-2.1"发布于 2017-10-29 22:04:11
这里有一个类似于杰夫·默卡多的解决方案,它使用tostream和flatten。
tostream | select(length==2) | .[0] |= map(strings) | flatten | join("/")另一种方法是使用递归函数来遍历输入,如
def slashpaths($p):
def concat($p;$k): if $p=="" then $k else "\($p)/\($k)" end;
if type=="array" then .[] | slashpaths($p)
elif type=="object" then
keys_unsorted[] as $k
| .[$k] | slashpaths(concat($p;$k))
else concat($p;.) end;
slashpaths("")发布于 2017-10-29 22:07:25
使用--stream很好,但下面的内容可能不那么深奥:
paths(scalars) as $p
| getpath($p) as $v
| ($p | map(strings) + [$v])
| join("/")(如果使用JQ1.4或更早版本,如果任何叶子可能是数字、布尔值或null,那么上面的[$v]应该替换为[$v|tostring])。
结果是否应该被视为“落叶之路”则是另一回事.
https://stackoverflow.com/questions/47004904
复制相似问题