我想合并两个JSON文件,其中基本文件(A)中的对象通过匹配文件(B)中的对象进行扩充,但不会覆盖A和B具有相同键的不同值的情况.

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

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

第二个JSON文件(B),具有相同的基本 struct ,但可 Select 使用其他键(本例中为metadata,但可以是任何键):

[
  {
    "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

这会将metadata加到A中,并为其他关键点保留A的值.然而,结果中缺少gamma个.从上面的示例中,我想要一个结果,其中:

  • Alpha应该有元数据
  • 贝塔应该是香蕉的,而不是蓝莓的.
  • 伽马应该在最终名单中
  • 欧米茄不应该出现在最终名单中
  • 应保持列表中对象的顺序.

我想要的是:

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

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

推荐答案

如果保证名称在一个文件中是唯一的,您可以暂时将文件A转换为INDEX,因此判断.name的包含性就变成了用has判断密钥.然后,在input[]上使用reduce迭代文件B的项,如果名称作为键出现,则通过将其旧值添加到当前项来更新相应的字段(顺序问题).最后,通过使用[.[]]将所有字段值收集到一个数组中,将对象 struct 恢复为一个array.

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相关问答推荐

使用相同的密钥值来命名Json并使用Jolt重命名密钥

如何在使用GO时检测JSON中不需要的字段?

抓取低于w jolt的对象级别

PowerShell脚本未按预期生成预期的JSON输出

Terraform迭代JSON文件以获取键值对

使用快速json库编写json可以消除所有缩进

419(未知状态)使用laravel处理PUT请求

Jolt 变换以展平 json 字符串数组

如何修复通过在 tsconfig.json 文件中添加allowImportingTsExtensions引发的错误 TS5023?

使用 TypeScript 接口时如何修复未定义错误?

JOLT 转换仅过滤一个字段

父键中的 Perl JSON 数组

如何让 JSON.NET 忽略对象关系?

Spring MVC控制器中的JSON参数

JSON.parse 返回字符串而不是对象

在 Webpack 中加载静态 JSON 文件

使用 jq 如何用其他名称替换键的名称

如何转换为 D3 的 JSON 格式?

MySQL Select JSON 字段属性具有值的位置

如何使用 Jackson 的 objectMapper 反序列化接口字段?