如何在Ansible中非递归保留字典顶层指定键?
问题
需要从字典列表中移除顶层(层级0)的部分键,仅保留指定顶层键后用unique过滤器去重。但ansible.utils.keep_keys过滤器是递归处理的——即使子键匹配规则,也会保留顶层不匹配的键,遇到整数列表时还会出现异常,无法得到预期结果。
示例代码:
- debug: msg: "{{ my_list | keep_keys(target=['key0', 'key1']) | unique }}" vars: my_list: - key0: A key1: B key2: - 1 key3: foo - key0: A key1: B key2: - 2 key4: bar
实际输出:
msg: - key0: A key1: B key2: - 1 - key0: A key1: B key2: - 2
期望输出:
msg: - key0: A key1: B
remove_keys同样不适用,因为它也是递归处理,且需要移除的键数量远多于需要保留的键。想知道除了自行开发过滤器外,有没有其他实现方式?
解决方案
用Ansible原生的dict2items、selectattr和items2dict过滤器组合,就能实现仅保留顶层指定键的需求,完全不会递归处理子结构,步骤如下:
- 先把列表里的每个字典转成键值对列表(
dict2items); - 筛选出顶层键在目标列表中的项(
selectattr('key', 'in', ['key0', 'key1'])); - 再把筛选后的键值对转回字典(
items2dict); - 最后用
unique去重。
完整示例:
- debug: msg: "{{ my_list | map('dict2items') | map('selectattr', 'key', 'in', ['key0', 'key1']) | map('items2dict') | unique }}" vars: my_list: - key0: A key1: B key2: - 1 key3: foo - key0: A key1: B key2: - 2 key4: bar
运行这段代码就能得到你想要的期望输出。
内容的提问来源于stack exchange,提问作者stackprotector
相关产品推荐
相关产品推荐

