如何使用jq查找某个键的所有路径

时间:2016-09-30 22:05:26

标签: json key extract jq

在一个非常大的嵌套json结构中,我试图找到以键结尾的所有路径。

例如:

{
  "A": {
    "A1": {
      "foo": {
        "_": "_"
      }
    },
    "A2": {
      "_": "_"
    }
  },
  "B": {
    "B1": {}
  },
  "foo": {
    "_": "_"
  }
}

会打印出以下内容: [“A”,“A1”,“foo”],[“foo”]

不幸的是我不知道键的嵌套级别会出现什么级别,所以我无法通过简单的选择来解决问题。我与jq '[paths] | .[] | select(contains(["foo"]))'关系密切,但输出包含任何包含foo的树的所有排列。 输出:["A", "A1", "foo"]["A", "A1", "foo", "_"]["foo"][ "foo", "_"]

如果我可以保留原始数据结构格式但只是过滤掉所有不包含密钥的路径(在这种情况下,“foo”下的子树不需要隐藏),可以获得奖励积分。

2 个答案:

答案 0 :(得分:10)

输入您的信息:

$ jq -c 'paths | select(.[-1] == "foo")' 
["A","A1","foo"]
["foo"]

奖励积分:

(1)如果你的jq有tostream

$ jq 'fromstream(tostream| select(.[0]|index("foo")))'

或者更好的是,由于您的输入很大,您可以将流解析器(jq -n --stream)与此过滤器一起使用:

fromstream( inputs|select( (.[0]|index("foo"))))

(2)你的jq是否有tostream

. as $in
| reduce (paths(scalars) | select(index("foo"))) as $p
    (null; setpath($p; $in|getpath($p))))

在所有三种情况下,输出为:

{
  "A": {
    "A1": {
      "foo": {
        "_": "_"
      }
    }
  },
  "foo": {
    "_": "_"
  }
}

答案 1 :(得分:0)

我遇到了同样的基本问题。

使用(yaml)输入如:

developer:
  android:
    members:
    - alice
    - bob
    oncall:
    - bob
hr:
  members:
  - charlie
  - doug
this:
  is:
    really:
      deep:
        nesting:
          members:
          - example deep nesting

我想找到所有任意嵌套的组并获取它们的成员。

使用:

yq . | # convert yaml to json using python-yq
    jq ' 
    . as $input | # Save the input for later
    . | paths | # Get the list of paths 
        select(.[-1] | tostring | test("^(members|oncall|priv)$"; "ix")) | # Only find paths which end with members, oncall, and priv
        . as $path | # save each path in the $path variable
    ( $input | getpath($path) ) as $members | # Get the value of each path from the original input
    {
        "key": ( $path | join("-") ), # The key is the join of all path keys
        "value": $members  # The value is the list of members
    }
    ' |
    jq -s 'from_entries' | # collect kv pairs into a full object using slurp
    yq --sort-keys -y . # Convert back to yaml using python-yq

我得到这样的输出:

developer-android-members:
  - alice
  - bob
developer-android-oncall:
  - bob
hr-members:
  - charlie
  - doug
this-is-really-deep-nesting-members:
  - example deep nesting