基于公共键值对使用jq合并两个JSON文件的方案求助
合并两个JSON文件中相同插件的Installation列表
你有两个结构一致的JSON文件,需要合并它们的Plugins数组,将相同Name的插件的Installation数组合并,不同的插件保留原样。
输入文件
File1.json
{ "Plugins": [ { "Name": "Plugin A", "Installation": [ { "Version": "1.0", "Server" : "abc" } ] }, { "Name": "Plugin B", "Installation": [ { "Version": "2.0", "Server" : "abc" } ] }, { "Name": "Plugin C", "Installation": [ { "Version": "2.0", "Server" : "abc" } ] } ] }
File2.json
{ "Plugins": [ { "Name": "Plugin A", "Installation": [ { "Version": "1.1", "Server" : "xyz" } ] }, { "Name": "Plugin B", "Installation": [ { "Version": "2.0", "Server" : "xyz" } ] } ] }
期望输出
{ "Plugins": [ { "Name": "Plugin A", "Installation": [ { "Version": "1.0", "Server" : "abc" }, { "Version": "1.1", "Server" : "xyz" } ] }, { "Name": "Plugin B", "Installation": [ { "Version": "2.0", "Server" : "abc" }, { "Version": "2.0", "Server" : "xyz" } ] }, { "Name": "Plugin C", "Installation": [ { "Version": "2.0", "Server" : "abc" } ] } ] }
解决方案
1. 使用jq工具实现(推荐)
jq是处理JSON的轻量强大工具,一行命令就能完成这个合并需求。执行以下命令:
jq -n ' [inputs.Plugins[]] | group_by(.Name) | map({ Name: .[0].Name, Installation: [.[].Installation[]] }) | {Plugins: .} ' File1.json File2.json
命令解释:
-n:启用null输入模式,允许我们同时处理多个输入文件[inputs.Plugins[]]:将两个文件中的Plugins数组展开,合并成一个包含所有插件对象的大数组group_by(.Name):按照插件的Name字段分组,相同名称的插件会被归为同一组map(...):遍历每个分组,构造新的插件对象:Name: .[0].Name:取分组中第一个对象的Name(同一组内所有插件的Name都一致)Installation: [.[].Installation[]]:将分组内每个插件的Installation数组展开后合并成一个新数组
{Plugins: .}:将处理后的插件数组包装成最终的JSON结构
如果需要将结果保存到文件,只需在命令末尾追加 > merged.json即可。
2. Shell脚本封装
如果需要重复使用这个合并功能,可以把jq命令封装成Shell脚本:
#!/bin/bash # 检查输入参数是否合法 if [ $# -ne 2 ]; then echo "用法: $0 <File1.json> <File2.json>" exit 1 fi # 执行合并并将结果写入文件 jq -n ' [inputs.Plugins[]] | group_by(.Name) | map({ Name: .[0].Name, Installation: [.[].Installation[]] }) | {Plugins: .} ' "$1" "$2" > merged.json echo "合并完成!结果已保存到 merged.json"
使用方法:先给脚本添加执行权限chmod +x merge-json.sh,然后运行./merge-json.sh File1.json File2.json。
3. Jenkins Groovy脚本实现
如果需要在Jenkins Pipeline中完成这个合并操作,可以使用Groovy的JSON处理能力:
import groovy.json.JsonSlurper import groovy.json.JsonBuilder // 读取两个目标JSON文件 def file1 = new File('File1.json') def file2 = new File('File2.json') def slurper = new JsonSlurper() def data1 = slurper.parse(file1) def data2 = slurper.parse(file2) // 用Map分组存储插件的Installation列表,key为插件名称 def pluginsMap = [:].withDefault { [] } // 处理第一个文件的插件数据 data1.Plugins.each { plugin -> pluginsMap[plugin.Name].addAll(plugin.Installation) } // 处理第二个文件的插件数据 data2.Plugins.each { plugin -> pluginsMap[plugin.Name].addAll(plugin.Installation) } // 构造最终的JSON结构 def mergedPlugins = pluginsMap.collect { name, installations -> [Name: name, Installation: installations] } def mergedJson = new JsonBuilder([Plugins: mergedPlugins]) // 将合并结果写入文件 new File('merged.json').text = mergedJson.toPrettyString() println "JSON合并完成,结果已保存到 merged.json"
你可以把这段代码放到Jenkins Pipeline的script块中,或者作为独立Groovy脚本运行(需确保环境已安装Groovy及JSON依赖)。
内容的提问来源于stack exchange,提问作者Sarvesh




