【问题标题】:Finding the path to all occurrences of a specific key is a specify value查找特定键的所有出现的路径是指定值
【发布时间】:2026-02-09 12:35:01
【问题描述】:

我有一堆十万行 json 文件,我正在尝试弄清楚它们的结构。

我想打印所有名为“ENTITY”且值为“TEXT”的键的路径。

这些可以嵌套在任何级别。有很多示例可以在特定级别找到一个,例如Select objects based on value of variable in object using jq

但我实际上是想弄清楚这些项目的嵌套位置,因为文件太大,我无法通过检查来做到这一点。

【问题讨论】:

    标签: json jq


    【解决方案1】:
    paths( objects | .ENTITY == "TEXT" )
    

    根据需要格式化输出。例如,

    jq -r 'paths( objects | .ENTITY == "TEXT" ) | join(".")'
    

    jqplay


    [以下是我原来的答案]

    path( .. | select( type == "object" and .ENTITY == "TEXT" ) )
    

    根据需要格式化输出。例如,

    jq -r 'path( .. | select( type =="object" and .ENTITY == "TEXT" ) ) | join(".")'
    

    jqplay

    【讨论】:

    • 提供了一个更简单的解决方案
    【解决方案2】:

    如果我正确理解了您的问题,那么您正在搜索具有给定键/字段且其值与给定值匹配的叶子。这种方法使用leaf_paths 获取所有叶子以及getpath 来获取它们的值,transpose 将它们组合起来,最后使用select 将列表减少到符合条件的那些。输出只是路径数组。

    jq --arg key "ENTITY" --arg value "TEXT" '
      [[leaf_paths],[getpath(leaf_paths)]]
      | transpose
      | map(select(.[0][-1] == $key and .[1] == $value))[][0]
    '
    

    【讨论】:

    • 这个答案也有效。由于某种原因,ikegami 的答案运行速度大约是 5 倍。
    • 如果我猜的话,那是因为我的方法过滤得早,而这种方法构造了大量最终会被丢弃的数组。
    • 提示:“leaf_paths弃用,将在下一个主要版本中删除。”请改用paths(scalars)
    • 我认为您想到的方法更接近:leaf_paths as $p | [$p, getpath($p)] | select(.[0][-1] == $key and .[1] == $value)
    • 也就是说,上面可以优化为paths(. == $value) | select(.[-1] == $key)。不过,我仍然更喜欢我的 (paths( objects | .ENTITY == "TEXT" ))。 1) 它给出了对象的路径,而不是以ENTITY 结束所有路径。 2)它更干净。 3) 越早过滤也应该越快。
    最近更新 更多