Filter Ansible筛选字典列表,使其仅在一个字段中包含唯一值
我有一个ansible变量中的字典列表。有些词典在字段Filter Ansible筛选字典列表,使其仅在一个字段中包含唯一值,filter,ansible,jinja2,Filter,Ansible,Jinja2,我有一个ansible变量中的字典列表。有些词典在字段'id和字段'name'中具有相同的值,而在其他键值对中则不同(这对我来说并不重要)。我想过滤掉所有关于'name'和'id'字段的“重复”字典 例如: [{ "name": "abc", "id": "123456", "other_key": "unimportant value" }, { "name": "abc", "id": "123456",
'id
和字段'name'
中具有相同的值,而在其他键值对中则不同(这对我来说并不重要)。我想过滤掉所有关于'name'
和'id'
字段的“重复”字典
例如:
[{
"name": "abc",
"id": "123456",
"other_key": "unimportant value"
},
{
"name": "abc",
"id": "123456",
"other_key": "another unimportant value"
},
{
"name": "bcd",
"id": "789012",
"other_key": "unimportant value"
}]
预期结果:
[{
"name": "abc",
"id": "123456"
},
{
"name": "bcd",
"id": "789012"
}]
如何在Ansible中实现这一点?(不一定要丢弃'other_key'
变量,也可能只是第一次出现,这无关紧要)
我已经生成了一个唯一ID列表,其中包含:
{{ mydictionaries | map(attribute='id') | unique | list }}
但是如何使用此选项过滤字典列表?您可以使用从地图列表中仅过滤所需的键,然后应用
唯一的过滤器
{{ mydictionnaries | json_query('[].{"name": name, "id": id}') | unique }}
下面是概念验证剧本。请注意,在上述文档中,json_query
要求在ansible控制器上安装pip jmespath
---
- name: Unique filtered dictionaries list example
hosts: localhost
gather_facts: false
vars:
mydictionaries: [{"name": "abc","id": "123456","other_key": "unimportant value"},{"name": "abc","id": "123456","other_key": "another unimportant value"},{"name": "bcd","id": "789012","other_key": "unimportant value"}]
tasks:
- name: Filter out list as wanted
debug:
msg: >-
{{
mydictionaries
| json_query('[].{"name": name, "id": id}')
| unique
}}
给
PLAY [Unique filtered dictionaries list example] *************************************************************************************************************************************************************************************************************************************
TASK [Filter out list as wanted] ****************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"id": "123456",
"name": "abc"
},
{
"id": "789012",
"name": "bcd"
}
]
}
PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Q:“过滤掉与‘name’和‘id’字段相关的“重复”字典。”
答:假设数据存储在变量my_list
中,我们将从name
和id
属性创建的hash
属性添加到列表中。比如说
- set_fact:
my_list2: "{{ my_list2|default([]) +
[item|combine({'hash': (item.name ~ item.id)|hash})] }}"
loop: "{{ my_list }}"
- debug:
var: my_list2
- set_fact:
my_list3: "{{ my_list3|default([]) +
[{'name': item.1.0.name, 'id': item.1.0.id}] }}"
loop: "{{ my_list2|groupby('hash') }}"
- debug:
var: my_list3
给予
接下来使用过滤器并选择所需的属性。比如说
- set_fact:
my_list2: "{{ my_list2|default([]) +
[item|combine({'hash': (item.name ~ item.id)|hash})] }}"
loop: "{{ my_list }}"
- debug:
var: my_list2
- set_fact:
my_list3: "{{ my_list3|default([]) +
[{'name': item.1.0.name, 'id': item.1.0.id}] }}"
loop: "{{ my_list2|groupby('hash') }}"
- debug:
var: my_list3
给予
谢谢,这真是太棒了!但是,我必须删除json_查询中的引号,即
json_查询('[].{name:name,id:id}')
才能使其正常工作。谢谢,这也很有效。我选择Zeitounator的解决方案来解决当前的问题,因为它只需一步(更少的代码)。但是,您的解决方案的优点是,它也可以在ansible控制器上不依赖jmespath的情况下工作,这在许多情况下肯定很方便。这个比较复杂。除此之外,它还可以按任意键组合进行排序(例如id[0:2])。