Ansible中如何按相同匹配键合并两个JSON文件的对应字段值
正确实现方案
错误根因
gp_value返回空数组是因为匹配逻辑未正确关联两个JSON的对应字段,或存在部分networkId在gpidmgmtfinal.json中无匹配的gpfinalnet,此时调用first过滤器就会触发空序列报错。
方案1:Ansible/Jinja2 实现(适配你提到的first过滤器使用场景)
核心逻辑
先构建gpfinalnet到gpfinalgpid的映射字典,避免循环查找空匹配问题:
# 加载两个JSON文件 - name: 加载源数据 ansible.builtin.set_fact: gpid_mgmt: "{{ lookup('file', 'gpidmgmtfinal.json') | from_json }}" gp_test: "{{ lookup('file', 'gp-test.json') | from_json }}" # 构建匹配映射表 - name: 生成网络ID到GPID的映射 ansible.builtin.set_fact: net_gpid_map: "{{ net_gpid_map | default({}) | combine({item.gpfinalnet: item.gpfinalgpid}) }}" loop: "{{ gpid_mgmt }}" # 合并字段到目标JSON - name: 合并数据 ansible.builtin.set_fact: merged_result: "{{ merged_result | default([]) + [item | combine({'gpfinalgpid': net_gpid_map[item.networkId] | default(omit)})] }}" loop: "{{ gp_test }}"
default(omit)会自动跳过无匹配的条目,不会生成空值也不会触发报错。
方案2:Python 实现
import json # 读取源文件 with open("gpidmgmtfinal.json", "r", encoding="utf-8") as f: gpid_data = json.load(f) with open("gp-test.json", "r", encoding="utf-8") as f: test_data = json.load(f) # 构建映射表 net_gpid_map = {item["gpfinalnet"]: item["gpfinalgpid"] for item in gpid_data} # 合并字段 for item in test_data: if item["networkId"] in net_gpid_map: item["gpfinalgpid"] = net_gpid_map[item["networkId"]] # 输出结果 with open("merged_gp_result.json", "w", encoding="utf-8") as f: json.dump(test_data, f, indent=2, ensure_ascii=False)
输出示例
[ { "networkId": "net_001", "name": "办公网络", "gpfinalgpid": "gpid_67821" }, { "networkId": "net_002", "name": "生产网络", "gpfinalgpid": "gpid_90347" } ]
内容的提问来源于stack exchange,提问作者Vinny
相关产品推荐
相关产品推荐

