使用 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"
用于obj1
和obj2
,"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的主要内容,如果未能解决你的问题,请参考以下文章