16

我有一个由科学仪器创建的分层深度 JSON 对象,因此该文件有点大(1.3MB)并且不容易被人们阅读。我想获取 JSON 对象的键列表,直到一定深度。例如,给定一个像这样的输入对象

{
    "acquisition_parameters": {
        "laser": {
            "wavelength": {
                "value": 632,
                "units": "nm"
            }
        },
        "date": "02/03/2525",
        "camera": {}
    },
    "software": {
        "repo": "github.com/username/repo",
        "commit": "a7642f",
        "branch": "develop"
    },
    "data": [{},{},{}]
}

我想要这样的输出。

{
    "acquisition_parameters": [
        "laser",
        "date",
        "camera"
    ],
    "software": [
        "repo",
        "commit",
        "branch"
    ]
}

这主要是为了能够枚举 JSON 对象中的内容。从仪器处理 JSON 对象后开始发散:例如,有些可能有一个字段,例如.frame.cross_section.stats.fwhm,而另一些可能有.sample.species,因此能够在命令行上查询 JSON 对象会很方便。

4

3 回答 3

12

以下应该完全符合您的要求

jq '[(keys - ["data"])[] as $key | { ($key): .[$key] | keys }] | add'

这将使用上述输入提供以下输出:

{
  "acquisition_parameters": [
    "camera",
    "date",
    "laser"
  ],
  "software": [
    "branch",
    "commit",
    "repo"
  ]
}
于 2015-02-11T03:10:43.707 回答
6

鉴于您的目的,您可能会更轻松paths地使用内置函数列出输入中的所有路径,然后在所需深度截断:

$  echo '{"a":{"b":{"c":{"d":true}}}}' | jq -c '[paths|.[0:2]]|unique'
[["a"],["a","b"]]
于 2014-06-19T06:49:19.990 回答
1

这是另一个使用reducesetpath的变体,它假设您有一组特定的要检查的顶级键:

  . as $v
| reduce ("acquisition_parameters", "software") as $k (
     {}; setpath([$k]; $v[$k] | keys)
  )
于 2017-08-02T07:33:14.103 回答