我有嵌套对象的JSON
{
"schema1": {
"table1": {
"status": 0
},
"table2": {
"status": 1
}
},
"schema2": {
"table1": {
"status": 0
},
"table2": {
"status": 1
}
}
}
我需要在schema.table列表中按状态== 1过滤。 我的第一个方法是
.[]|.[]|(select(.status==1))|"table.schema \(.status)"
如何用父对象的适当键替换table.schema?
预期结果是:
[ "schema1.table2", "schema2.table2" ]
答案 0 :(得分:2)
我选择了这样的解决方案
path(.[]|.[]|select(.status==1))|join(".")
答案 1 :(得分:0)
jq
解决方案:
jq -r '. as $o | paths
| select(length == 3)
| select($o[.[0]][.[1]][.[2]] == 1)
| .[0] +"."+ .[1]' file.json
输出:
schema1.table2
schema2.table2
答案 2 :(得分:0)
以下使用to_entries
(两次)按要求生成数组:
[to_entries[]
| .key as $k
| .value | to_entries | map(select(.value.status == 1))[]
| [$k, .key]
| join(".") ]
答案 3 :(得分:0)
如果输入文档太大而不适合内存,那么使用jq的流解析器的解决方案是合适的。
为此,请考虑program.jq如下:
select(length==2 and .[-1] == 1 and .[0][-1] == "status")
| .[0][:-1]
| join(".")
(这里[:-1]
是一种写[0:-1]
的简洁方式,实际上除了数组中的最后几项外,它们都是。)
调用:jq --stream -f program.jq input.json
会生成流:
"schema1.table2"
"schema2.table2"
如果需要值数组,则可以将此流传输到jq -s .
另请注意,上面的program.jq实际上解决了嵌套可以任意深度的一般问题。
答案 4 :(得分:0)
在这种情况下,您可以使用paths(scalars)
(以前为leaf_paths
)来获取所有标量值的路径。使用这些路径,您可以使用getpath/1
获取值并输出所需的字符串。
paths(scalars) as $p
| select($p[-1] == "status" and getpath($p) == 1)
| "\([$p[1,0]] | join(".")) \(getpath($p))"
如果你想获得想象力,你也可以使用流来一次性获取路径和值。
tostream as [$p,$v]
| select($p[-1] == "status" and $v == 1)
| "\([$p[1,0]] | join(".")) \($v)"
但考虑到你的评论,如果你只是需要这些路径,那么它们可以简单地归结为:
[tostream as [$p,$v]
| select($p[-1] == "status" and $v == 1)
| $p[:2] | join(".")
]