合并不同键上的 JSON 数组

合并不同键上的 JSON 数组

我有 2 个带有数组的 JSON 文件(在 bash 中使用curl 从restAPI 中提取)。这两个文件都是数组,.result顶部有一个需要保留的对象。第一个有一个.name字段和许多(超过 100 个)其他字段,其中包括.ip_address空白字段。第二个包含附加信息,例如接口和 IP 地址以及不同字段名称中的名称(键)。第一个文件中的键与第二个文件中的键不同,但应该相关(当然我之前可以更改键字段名称,并且键的数据通常是大小写混合的)

ip_address我想合并它们,以便覆盖第一个 JSON,其中.name字段相同并添加附加数据:

我知道它要么是数组相乘,要么是减少和添加,但根据已经找到的示例,我无法得到正确的结果。对于解决方案,我将不胜感激。

服务器:

{
  "result": [
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER1",
      "ip_address": ""
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER2",
      "ip_address": ""
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "server3",
      "ip_address": ""
     },
    {
      "os": "Microsoft Windows Server 2016 Standard",
      "name": "server4",
      "ip_address": ""
     }
  ]
}

ips.txt

{
  "result": [
    {
      "interface": "Intel Wireless-AC 9560 160MHz",
      "cmdb.name": "server1",
      "ip_address": "10.0.0.10"
    },
    {
      "interface": "Wi-Fi",
      "cmdb.name": "server2",
      "ip_address": "10.0.0.10"
    },
    {
      "interface": "Intel Dual Band Wireless-AC 8265",
      "cmdb.name": "server4",
      "ip_address": "10.0.0.10"
    }
  ]
}

服务器数据的期望输出是:

{
  "result": [
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER1",
      "interface": "Intel Wireless-AC 9560 160MHz",
      "ip_address": "10.0.0.10"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER2",
      "interface": "Wi-Fi",
      "ip_address": "10.0.0.10"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "server3",
      "ip_address": ""
     },
    {
      "os": "Microsoft Windows Server 2016 Standard",
      "name": "server4",
      "interface": "Intel Dual Band Wireless-AC 8265",
      "ip_address": "10.0.0.10"
     }
  ]
}

答案1

下面使用关系JOIN()函数 injq将两个数组的元素连接起来,这些元素对于密钥(服务器)和密钥(IP)result的小写变体相等。它还用于构建 IP 文件数组的索引。该函数为我们提供了使用该函数合并的匹配对象的数组(示例中的对)。在加入和合并之后,我们留下了同时包含和键的对象,因此我们在每个对象中删除后者。namecmdb.nameINDEX()resultJOIN()addnamecmdb.name

jq '.result = [JOIN(INDEX(input.result[]; ."cmdb.name"|ascii_downcase); .result[]; .name|ascii_downcase) | add | del(."cmdb.name")]' servers.json ips.json

表达式jq的格式很好:

.result =
  [
    JOIN(
      # index on the second file's .cmdb.name key in each result object
      INDEX(
        input.result[];
        ."cmdb.name" | ascii_downcase
      );
      .result[];             # join on the first file's result objects
      .name | ascii_downcase # match using the .name key
    )
    | add               # merge the matched objects
    | del(."cmdb.name") # delete that key we don't want
  ]

结果:

{
  "result": [
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER1",
      "ip_address": "10.0.0.10",
      "interface": "Intel Wireless-AC 9560 160MHz"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER2",
      "ip_address": "10.0.0.10",
      "interface": "Wi-Fi"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "server3",
      "ip_address": ""
    },
    {
      "os": "Microsoft Windows Server 2016 Standard",
      "name": "server4",
      "ip_address": "10.0.0.10",
      "interface": "Intel Dual Band Wireless-AC 8265"
    }
  ]
}

相关内容