我有 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 文件数组的索引。该函数为我们提供了使用该函数合并的匹配对象的数组(示例中的对)。在加入和合并之后,我们留下了同时包含和键的对象,因此我们在每个对象中删除后者。name
cmdb.name
INDEX()
result
JOIN()
add
name
cmdb.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"
}
]
}