使用jq将JSON扁平化,保留键名

3

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

使用jq,我想要得到的只是一个包含所有底层对象的对象数组,每个对象都有一个额外的键/值对,用于标识其原始所属的顶层键。

换句话说,我想将JSON转换为

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

转换为简单数组
[OBJ1, OBJ2, OBJ3]

其中每个OBJi都是具有额外键值对的原始对象

"parent-key-name": keyx

在这里,keyx 是顶层键 obji 所属的键,即对于 obj1obj2"key1" 为顶层键,而对于 obj3,则为"key2"

我遇到了一个问题,当引用底层对象时,例如通过 .[],jq似乎没有内置功能来访问相关的顶层信息。然而,我是jq的新手,并希望最终有一个简单的解决方案。

2个回答

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 as $parent | .value[] | .["parent-key-name"] = $parent] 或者 [ to_entries[] | .key as $parent | .value[] + { "parent-key-name": $parent} ]。 - peak

1
以下解决方案包括两个步骤,每个步骤都可以单独使用,例如,如果有人想以稍微不同的方式“压平”JSON。
1. 首先,让我们“原地”更改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,"parent-key-name":"key2"}]]。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接