json - 使用 JQ 合并 JSON 列表中的对象

标签 json jq

我想要合并两个 JSON 文件,其中基础文件 (A) 中的对象通过文件 (B) 中的匹配对象进行扩充,但不会被覆盖,因为 A 和 B 的同一键具有不同的值。

例如,我有一个 JSON 文件 (A),其内容如下

[
  {
    "name": "alpha",
    "value": "apple"
  },
  {
    "name": "beta",
    "value": "banana"
  },
  {
    "name": "gamma",
    "value": "guava"
  }
]

和第二个 JSON 文件 (B),具有相同的基本结构,但可选地具有附加键(本例中为元数据,但它可以是任何内容):

[
  {
    "name": "alpha",
    "value": "apple",
    "metadata": {
      "types": [
        "granny"
      ]
    }
  },
  {
    "name": "beta",
    "value": "blueberry"
  },
  {
    "name": "omega",
    "value": "orange"
  }
]

我想将两个列表合并在一起,B 中对象的键/值被添加到 A 中的同一个对象(由 name 匹配)中。我的 JQ 实现这一点的方法如下:

jq -s '[ .[0][] as $a | .[1][] as $b | select ($a.name == $b.name) | $a * $b ]' b.json a.json

这可以将元数据添加到A中并保留A的其他键值。但是,结果中缺少 gamma。从上面的示例中,我想要一个结果:

  • alpha 应该有元数据
  • beta 应该是香蕉,而不是蓝莓。
  • gamma 应该在最终列表中
  • omega 不应出现在最终列表中
  • 应保持列表中对象的顺序。

我想要这个:

[
  {
    "name": "alpha",
    "value": "apple"
    "metadata": {
      "types": [
        "granny"
      ]
    }
  },
  {
    "name": "beta",
    "value": "banana"
  },
  {
    "name": "gamma",
    "value": "guava"
  }
]

如何调整此查询以包含来自 A 的顶级对象,但不包含来自 B 的顶级对象?

最佳答案

如果保证名称在一个文件中是唯一的,您可以暂时将文件 A 转换为 INDEX,因此检查 .name 的包含性就变成了以下问题使用 has 检查 key 。然后,在 input[] 上使用 reduce 迭代文件 B 的项目,如果名称作为键存在,则通过将其旧值添加到当前项目(订单事宜)。最后,使用 [.[]] 将所有字段值收集到数组中,将对象结构恢复为数组。

jq 'reduce input[] as $i (INDEX(.name);
  if has($i.name) then .[$i.name] |= $i + . end
) | [.[]]' fileA.json fileB.json
[
  {
    "name": "alpha",
    "value": "apple",
    "metadata": {
      "types": [
        "granny"
      ]
    }
  },
  {
    "name": "beta",
    "value": "banana"
  },
  {
    "name": "gamma",
    "value": "guava"
  }
]

Demo

关于json - 使用 JQ 合并 JSON 列表中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77299198/

相关文章:

json - 交换键和数组值,将旧键转换为新数组值,使用 jq

javascript - 我如何为这个庞大的对象列表中的每个对象添加一个额外的键和值

c# - 无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List` 1

json - 如何合并两个 ARM 模板 JSON 参数文件并覆盖重复参数?

java - Gson:将 double 值格式化为小数点后 4 位

jq - 如何组合 2 个独立滤波器的输出

javascript - Bootstrap Accordion 。保留多个面板的页面加载状态

json - 比较两个 json 文件 : shell scripting

json - Bash 脚本/JSON - 从 {"Key":"Duration","Value":"N"中提取数值}

json - 如何通过jq选择键和子对象属性?