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

Ansible中map(regex_replace)后列表对比及重复项排查

问题解答

1. 标准化list3以实现正确的difference对比

问题原因

原代码直接对整个字典执行map('ansible.builtin.regex_replace'),导致list3的元素变成了字符串类型,而list2的元素是字典类型。difference过滤器无法在不同类型的元素间做有效对比,因此得不到预期的差异结果。

解决方案

仅针对list1中每个字典的name字段做正则替换,保持元素的字典结构不变。可以通过列表推导式结合combine过滤器实现:

- name: Debug
  hosts: "localhost"
  gather_facts: no
  connection: local

  vars: 
    list1: 
      - {name: aBC_SOMEITEM-A01_dEF, type: random, policy: one}
      - {name: aBC_SOMEITEM-A02_dEF, type: random, policy: two}
      - {name: aBC_SOMEITEM-A03_dEF, type: random, policy: three}

    list2: 
      - {name: "SOMEITEM-A01", type: "random", policy: "one"}
      - {name: "SOMEITEM-A02", type: "random", policy: "two"}
      - {name: "SOMEITEM-A03", type: "random", policy: "three"}
      - {name: "SOMEITEM-A03", type: "random", policy: "three"}
      - {name: "SOMEITEM-A04", type: "random", policy: "four"}

    # 标准化list3:仅清洗name字段,保留字典结构
    list3: >-
      {% set normalized_list = [] %}
      {% for item in list1 %}
        {% set cleaned_name = item.name | regex_replace('aBC_|_dEF', '') %}
        {% set _ = normalized_list.append(item | combine({'name': cleaned_name})) %}
      {% endfor %}
      {{ normalized_list }}

  tasks: 
  - debug: 
      msg: "{{ list2 | difference(list3) | to_yaml(default_flow_style=none) }}"

执行结果

此时difference可正确对比两个字典列表,输出预期差异项:

- {name: SOMEITEM-A04, policy: four, type: random}

2. 找出list2中的重复字典项

基础解决方案

利用groupby过滤器将完全相同的字典分组(以字典的JSON字符串作为分组键),筛选出分组长度大于1的项即为重复项:

tasks:
  - name: 提取list2中的重复项
    set_fact:
      duplicate_items: >-
        {% set grouped_items = list2 | groupby('to_json') %}
        {% set duplicates = [] %}
        {% for key, items in grouped_items %}
          {% if items | length > 1 %}
            {% set _ = duplicates.append(items[0]) %}
          {% endif %}
        {% endfor %}
        {{ duplicates }}

  - debug:
      msg: "{{ duplicate_items | to_yaml(default_flow_style=none) }}"

执行结果

输出list2中的重复字典:

- {name: "SOMEITEM-A03", policy: "three", type: "random"}

大数据集优化

如果处理超大列表,模板循环效率较低,可编写自定义过滤器插件:

  1. 在Ansible的过滤器目录(如filter_plugins/)创建list_utils.py:
def find_duplicates(input_list):
    seen = {}
    duplicates = []
    for item in input_list:
        # 将字典转为可哈希的有序元组,保证相同结构的字典能匹配
        key = tuple(sorted(item.items()))
        if key in seen:
            if seen[key] == 1:
                duplicates.append(item)
            seen[key] += 1
        else:
            seen[key] = 1
    return duplicates

class FilterModule(object):
    def filters(self):
        return {
            'find_duplicates': find_duplicates
        }
  1. 在Playbook中调用自定义过滤器:
tasks:
  - debug:
      msg: "{{ list2 | find_duplicates | to_yaml(default_flow_style=none) }}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:12:06