You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Ansible或jq按字段匹配合并两个JSON数组?

解决方案

问题出在你直接用combine时没有为每个运行信息条目匹配对应的服务器详细数据,而是把同一个值合并到了所有条目里。正确的做法是先把服务器详细数组转成以name为键的字典,再逐个匹配合并。

步骤1:加载两个JSON文件

先通过lookup加载并解析两个JSON文件:

- name: 加载服务器运行信息和详细信息JSON
  ansible.builtin.set_fact:
    run_info: "{{ lookup('file', 'run_info.json') | from_json }}"
    server_details: "{{ lookup('file', 'server_details.json') | from_json }}"

步骤2:将详细信息数组转为字典

把服务器详细信息数组转成以name为键的字典,这样可以快速通过server字段查找对应数据:

- name: 转换服务器详细信息为字典(name作为键)
  ansible.builtin.set_fact:
    server_details_dict: "{{ dict(server_details|map('community.general.dict_kv', 'name')) }}"

如果没有community.general模块,用原生写法替代:

server_details_dict: "{{ dict(server_details|json_query('[].{key: name, value: @}')|map('tuple')) }}"

步骤3:逐个匹配合并

遍历运行信息数组,每个条目通过server字段从字典中取出对应详细信息,再用combine合并:

- name: 合并两个数组数据
  ansible.builtin.set_fact:
    merged_servers: "{{ merged_servers | default([]) + [ item | combine(server_details_dict[item.server] | default({}), recursive=True) ] }}"
  loop: "{{ run_info }}"

default({})是为了处理运行信息中存在服务器名称但详细信息里没有的情况,避免报错。

示例效果

假设你的run_info.json内容是:

[
  {"playbook": "deploy.yml", "server": "web01", "status": "success"},
  {"playbook": "config.yml", "server": "db01", "status": "failed"}
]

server_details.json内容是:

[
  {"name": "web01", "fqdn": "web01.example.com", "env": "prod"},
  {"name": "db01", "fqdn": "db01.example.com", "env": "prod"},
  {"name": "cache01", "fqdn": "cache01.example.com", "env": "dev"}
]

合并后的merged_servers结果为:

[
  {"playbook": "deploy.yml", "server": "web01", "status": "success", "name": "web01", "fqdn": "web01.example.com", "env": "prod"},
  {"playbook": "config.yml", "server": "db01", "status": "failed", "name": "db01", "fqdn": "db01.example.com", "env": "prod"}
]

内容的提问来源于stack exchange,提问作者elmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:14:55