使用 jq 保留键名展平 JSON

Posted

技术标签:

【中文标题】使用 jq 保留键名展平 JSON【英文标题】:Flatten JSON with jq retaining key names 【发布时间】:2017-07-13 01:38:00 【问题描述】:

我正在尝试展平由嵌套对象组成的 JSON。顶层包含几个键/值对,其中每个值本身就是多个对象的数组(底层)。

我想使用 jq 得到的只是一个对象数组,其中包含底层的所有对象,每个对象都有一个附加的键/值对,用于标识它最初属于的顶层键。

也就是说,我想转一个JSON


 "key1": [obj1, obj2],
 "key2": [obj3]

放入一个普通数组

[OBJ1, OBJ2, OBJ3]

每个OBJi 只是带​​有额外键/值对的原始对象

"parent-key-name": keyx

其中keyx 将是obji 所属的顶层密钥,即"key1" 用于obj1obj2"key2" 用于obj3

我正在努力解决在引用底层对象时的事实,例如通过 .[],jq 似乎没有内置功能来访问相关的顶层信息。但是,我是 jq 的新手,希望有一个简单的解决方案。

【问题讨论】:

【参考方案1】:

下面介绍的解决方案包括两个步骤,每个步骤可能单独有用,例如如果有人想以稍微不同的方式“扁平化”JSON。

    首先,让我们“就地”对 obj[i] 进行更改:

    with_entries( .key as $k | .value[] |= ( . + "parent-key-name": $k ) )

例子:

$ jq -n -c -f program.jq

输入: "key1": [a:1, a:2], “key2”:[b:3]

输出:


  "key1": [
    
      "a": 1,
      "parent-key-name": "key1"
    ,
    
      "a": 2,
      "parent-key-name": "key1"
    
  ],
  "key2": [
    
      "b": 3,
      "parent-key-name": "key2"
    
  ]

    要扁平化,只需将| [.[]] 附加到上述过滤器即可。这会产生:

    [["a":1,"parent-key-name":"key1","a":2,"parent-key-name":"key1"],["b ":3,"父键名":"key2"]]

【讨论】:

【参考方案2】:

给定以下输入:


 "key1": ["name":"Emma","name":"Bob"],
 "key2": ["name":"Jean"]

您可以将项目划分为条目,将键存储在变量中,并将每个项目的值添加到 value 对象中:

jq  '[ to_entries[] | .key as $parent | .value[] |
   .["parent-key-name"] |= (.+ $parent) ] ' test.json

给出以下输出:

[
  
    "name": "Emma",
    "parent-key-name": "key1"
  ,
  
    "name": "Bob",
    "parent-key-name": "key1"
  ,
  
    "name": "Jean",
    "parent-key-name": "key2"
  
]

【讨论】:

这样写会更简单更好:[ to_entries[] | .key 作为 $parent | .值[] | .["parent-key-name"] = $parent] 或 [ to_entries[] | .key 作为 $parent | .value[] + "父键名": $parent ]

以上是关于使用 jq 保留键名展平 JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jq 从 JSON 中获取键名

JSON 键名中哪些字符有效/无效?

使用数组更改 JSON 的键名

使用 TSQL OPENJSON 如何从具有动态键名的 JSON 数组中提取值

PHP json转换 无键名数据格式转换为有键名格式

有没有办法在 JSON 文件的值中获取键名