繁体   English   中英

如何使用jq获取嵌套json的键和键类型

[英]How to get keys and key types of nested json using jq

我有一个像下面这样的文件 data.json -

     { 
       "parameter": {
        "colA": "No",
        "COLB": "No"
      },
      "workRequired": 0,
      "work": 0,
      "updateType": "AUTO"
}

我知道如何获取 json 的密钥和密钥类型 -

jq -c 'to_entries[] | [.key, (.value|type)]' data.json

但上面的命令返回我 -

["parmeter","object"]
["workRequired","string"]
["work","null"]
["updateType","number"]

但我希望命令像下面一样返回,以便我获得嵌套 json 的键类型 -

["parmeter"."colA","string"]
["parmeter"."colB","string"]
["workRequired","string"]
["work","null"]
["updateType","number"]

有什么办法可以使用jq

这非常接近请求的输出。

jq -c 'to_entries[] 
       | if .value|type == "object"
         then .key as $k 
            | .value
            | to_entries[]
            | ["\($k).\(.key)", (.value|type)]
         else [.key, (.value|type)]
         end'

输出:

["parameter.colA","string"]
["parameter.COLB","string"]
["workRequired","number"]
["work","number"]
["updateType","string"]

主要区别在于前两行。 我不认为["parameter"."colA","string']是有效的 json。

有些类型也不同。

解释

了解这些东西如何工作的一种方法是一步一步地学习。 所以从jq -c 'to_entries[]' ,看看结果是什么,然后依次添加每个步骤。 说明书也很不错。

在这里,我们从一个对象开始。 第一个命令是to_entries[] 引用手册,当“to_entries 被传递一个对象,然后对于输入中的每个 k: v 条目,输出数组包含 {"key": k, "value": v}。” 在末尾添加[]意味着输出将只是to_entries生成的数组中的对象。 所以这是第一步后的输出:

{"key":"parameter","value":{"colA":"No","COLB":"No"}}
{"key":"workRequired","value":0}
{"key":"work","value":0}
{"key":"updateType","value":"AUTO"}

现在我们有四个对象。 一个包含另一个对象。 原始问题涉及包含对象的对象。 问题是在最终输出中将包含对象的键与包含对象的键组合在一起。

条件if .value|type == "object"标识包含对象的对象。

当满足此条件时, .key as $k将包含对象的“key”键的值保存为名为 $k 的变量。

然后我们用包含的对象重复to_entries[] 包含对象是包含对象中键“值”的值。 代码.value | to_entries[] .value | to_entries[]通过to_entries[]过滤包含的对象。 这给了我们这两个对象。

{"key":"colA","value":"No"}
{"key":"COLB","value":"No"}

要创建所需的输出,我们需要构造一个数组,该数组将保存为 $k 的包含对象的键与这两个对象的元素组合在一起。 这是我们如何做到这一点。 (有关引号中的部分如何工作的说明,请参阅手册中的“字符串插值”。)

["\($k).\(.key)", (.value|type)]

对于每个对象,我们保存为变量 $k 的键与对象中“键”键的值组合在一起。 然后我们输出对象中“value”键的值的类型。

这产生了最终输出的前两行:

["parameter.colA","string"]
["parameter.COLB","string"]

现在我们转到条件的另一个分支。 这将处理第一步中不包含对象的三个对象。 在这里,我们只是重复问题中的原始代码,因为这是令人满意的。

else [.key, (.value|type)]

这产生了:

["workRequired","number"]
["work","number"]
["updateType","string"]

命令end结束条件。

还有一件事。 一开始的标志-c告诉 jq 我们想要紧凑的输出。 没有它,输出在逻辑上是相同的,但分布在多行上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM