Ansible合并JSON对象时避免重复字段值叠加的方法
Ansible合并JSON对象时避免字符串字段拼接,保留单一值并合并数组
问题场景
合并两个结构相似的JSON对象时,data数组能正常合并,但month、year这类字符串字段会被错误拼接(比如值为"1"和"1"的month字段会变成"11"),需要保留这类字段的单一值,同时正常合并数组。
输入JSON1
{ "data": [ { "item_value_01": "APPLICATION", "quantity": 1 }, { "item_value_01": "HERBERT", "quantity": 1 } ], "month": "1", "year": "2023" }
输入JSON2
{ "data": [ { "item_value_01": "Test", "quantity": 1 }, { "item_value_01": "Country", "quantity": 1 } ], "month": "1", "year": "2023" }
当前错误输出
{ "data": [ { "item_value_01": "APPLICATION", "quantity": 1 }, { "item_value_01": "HERBERT", "quantity": 1 }, { "item_value_01": "Test", "quantity": 1 }, { "item_value_01": "Country", "quantity": 1 } ], "month": "11", "year": "20232023" }
期望输出
{ "data": [ { "item_value_01": "APPLICATION", "quantity": 1 }, { "item_value_01": "HERBERT", "quantity": 1 }, { "item_value_01": "Test", "quantity": 1 }, { "item_value_01": "Country", "quantity": 1 } ], "month": "1", "year": "2023" }
问题原因
原playbook对所有字段统一使用+运算符处理:
- set_fact: list: "{{ list|default({})| combine({item: input1[item]|default([]) + input2[item]|default([])}, recursive=true) }}" loop: "{{ (input2.keys()|list + input1.keys()|list)|unique }}"
+运算符处理数组时是合并操作,但处理字符串时会执行拼接,这就导致month、year这类字符串字段被错误拼接。
解决方案
通过判断字段类型,对数组和非数组字段分别处理:数组字段执行合并,非数组字段保留单一值(优先取第一个JSON的字段值,若不存在则取第二个的)。
修改后的playbook:
- set_fact: merged_result: "{{ merged_result|default({})|combine({ item: (input1[item]|default([]) + input2[item]|default([])) if (input1[item] is iterable and input1[item] is not string) else input1[item]|default(input2[item]) }, recursive=true) }}" loop: "{{ (input1.keys()|list + input2.keys()|list)|unique }}"
代码解释
input1[item] is iterable and input1[item] is not string:判断当前字段是否为数组(排除字符串类型,因为字符串本身也是可迭代对象)- 数组类型字段:执行
+操作数组合并 - 非数组类型字段:优先使用
input1中的值,若input1没有该字段则使用input2的值(由于场景中两个JSON的对应字段值相同,最终结果一致)
运行该playbook后,即可得到符合预期的合并结果:data数组合并完整,month和year字段保留单一正确值。
内容的提问来源于stack exchange,提问作者Vinny
相关产品推荐
相关产品推荐

