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



我有带有嵌套对象的JSON

{
 "schema1": {
    "table1": {
        "status": 0
    },
    "table2": {
        "status": 1
    }
 },
 "schema2": {
    "table1": {
        "status": 0
    },
    "table2": {
        "status": 1
    }
 }
}

我需要按状态==1过滤的架构表列表。我的第一个方法是

.[]|.[]|(select(.status==1))|"table.schema  (.status)"

如何将表模式替换为父对象的适当键?

这是jq玩的例子

预期结果是:

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

我选择了这样的解决方案

path(.[]|.[]|select(.status==1))|join(".")

下面使用 to_entries(两次(根据请求生成数组:

[to_entries[]
 |  .key as $k
 | .value | to_entries | map(select(.value.status == 1))[]
 | [$k, .key]
 | join(".") ]

如果输入文档太大以至于无法舒适地放入内存中,那么使用 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 实际上解决了嵌套可以任意深度的一般问题。

jq解决方案:

jq -r '. as $o | paths 
       | select(length == 3) 
       | select($o[.[0]][.[1]][.[2]] == 1) 
       | .[0] +"."+ .[1]' file.json

输出:

schema1.table2
schema2.table2

在这种情况下,您可以使用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(".")
]

相关内容

  • 没有找到相关文章

最新更新