Ansible中如何将分组数据按位置合并为列表形式?
按地点分组转换Ansible数据的实现方法
直接用combine过滤器会因为键重复覆盖值,所以要借助groupby过滤器来实现分组收集,以下是可行的实现代码:
- name: 转换分组数据结构 hosts: localhost vars: groups: - name: grp1 location: newyork - name: grp2 location: newyork - name: grp3 location: paris tasks: - name: 生成按地点分组的locations结构 set_fact: locations: >- {{ groups | groupby('location') | items2dict(key_name='0', value_name='1') | dict2items | map('combine', {'value': item.value | map(attribute='name') | list}) | items2dict }} - name: 查看转换结果 debug: var: locations
步骤说明
groupby('location'):将原groups列表按location字段分组,得到形如[('newyork', [{}, {}]), ('paris', [{}])]的元组列表,每个元组的第一个元素是地点名,第二个是对应分组的原始对象列表。items2dict:把分组后的元组列表转换成字典,此时字典的value是原始group对象的列表。dict2items:将字典转回条目列表,方便逐个处理每个地点对应的group对象列表。map('combine', ...):遍历每个条目,把value替换成提取出的group name列表(用map(attribute='name')提取每个group的name字段,再转成列表)。items2dict:把处理后的条目列表转回最终的字典结构,就是你需要的格式。
原方法失败原因
直接使用combine时,当两个group的location相同时,后一个group的name会覆盖前一个,所以只能得到每个地点的最后一个group名称,无法生成列表。
内容的提问来源于stack exchange,提问作者Daniel Kupfer
相关产品推荐
相关产品推荐

