【问题标题】:How to get keys and key types of nested json using jq如何使用jq获取嵌套json的键和键类型
【发布时间】:2019-12-21 22:54:17
【问题描述】:

我有一个如下的文件 data.json -

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

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

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

【问题讨论】:

    标签: json types key jq


    【解决方案1】:

    这非常接近请求的输出。

    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[]' 开始,看看会发生什么,然后依次添加每个步骤。 manual也不错。

    在这里,我们从一个对象开始。第一个命令是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[] 通过to_entries[] 过滤包含的对象。这给了我们这两个对象。

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

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

    ["\($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 我们想要紧凑的输出。没有它,输出在逻辑上将是相同的,但会分布在多行中。

    【讨论】:

      猜你喜欢
      • 2018-04-08
      • 1970-01-01
      • 2017-12-15
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      • 2014-05-31
      相关资源
      最近更新 更多