如何在jq中的嵌套对象中获取父对象键?

时间:2018-03-23 10:52:40

标签: json path nested key jq

我有嵌套对象的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?

Here is jq play with example

预期结果是:

[ "schema1.table2", "schema2.table2" ]

5 个答案:

答案 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(".")
]