如何在Ansible中循环数组并匹配另一数组,无匹配时执行任务?
问题描述
现有两个JSON数组:
List1
[ { "DistinguishedName": "CN=Warren\\, Oscar J.,OU=Users,OU=Finance Division,OU=Departments,DC=domain,DC=local", "Name": "Warren, Oscar J.", "ObjectClass": "user", "mail": "Oscar.Warren@domain.local" }, { "DistinguishedName": "CN=Bodden\\, John B.,OU=Users,OU=Finance Division,OU=Departments,DC=domain,DC=local", "Name": "Bodden, John B.", "ObjectClass": "user", "mail": "John.Bodden@domain.local" } ]
List2
[ { "id": "ABC123", "userName": "john.bodden@domain.local" }, { "id": "DEF456", "userName": "oscar.warren@domain.local" } ]
需求:遍历List2中的每个userName,如果List1中没有mail值与之匹配的对象,则执行指定任务。
尝试的代码报错:
- debug: var: "{{ item }}" loop: "{{ List2 }}" when: "{{ List1 | selectattr('mail', 'equalto', item.userName) }}"
解决方案
你的代码报错有两个核心问题:
when条件不需要包裹{{ }},Ansible会自动解析条件表达式selectattr返回的是迭代器,需要转成列表后判断长度,确认是否存在匹配项
实现“List1中无匹配mail”逻辑的正确写法如下:
- name: 处理List2中无匹配的用户 debug: var: item loop: "{{ List2 }}" when: (List1 | selectattr('mail', 'equalto', item.userName | lower) | list | length) == 0
关键说明:
item.userName | lower:统一转小写,避免邮箱大小写差异导致的匹配失败selectattr('mail', 'equalto', ...):筛选List1中mail属性匹配的项| list | length:将筛选结果转为列表后获取长度,长度为0则表示无匹配项when直接写表达式,无需模板符号包裹
如果需要更灵活的忽略大小写匹配,也可以用match过滤器配合正则:
when: (List1 | selectattr('mail', 'match', '^' ~ item.userName ~ '$', 'i') | list | length) == 0
内容的提问来源于stack exchange,提问作者user1913559
相关产品推荐
相关产品推荐

