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

如何在Ansible中遍历YAML文件并打印所有键的完整路径与值?

问题描述

编写Ansible Playbook遍历input.yaml文件,要求打印每个键的完整路径及其对应值。当前代码能正常处理顶层键name、surname,但处理嵌套的address相关键时失败,报错:'dict object' has no attribute 'address.city'。

示例文件

input.yaml

name: Alice
surname: Smith
address:
  city: New York
  zipcode: 10001
contact:
  email: alice@example.com
  phone:
    home: 555-1234
    work: 555-5678

错误的Playbook(list.yaml)

- name: Print key-value pairs
  hosts: localhost
  vars_files:
    - input.yaml
  tasks:
    - name: Print top-level keys
      debug:
        msg: "{{ item.key }}: {{ my_vars[item.key] }}"
      loop: "{{ my_vars | dict2items }}"
      vars:
        my_vars: "{{ vars | dict2items | selectattr('key', 'in', ['name', 'surname', 'address', 'contact']) | items2dict }}"

解决方案

要处理嵌套字典,需要递归遍历所有层级的键值对,而非仅处理顶层。以下是两种可行实现方法:

方法1:使用递归Jinja2过滤器

通过自定义Jinja2递归过滤器生成完整路径与值的列表,再遍历打印:

- name: Recursively print all key-value paths
  hosts: localhost
  vars_files:
    - input.yaml
  tasks:
    - name: Generate recursive key-value list
      set_fact:
        recursive_items: >
          {%- set output = [] -%}
          {%- macro recurse(d, path='') -%}
            {%- for k, v in d.items() -%}
              {%- set current_path = path ~ k -%}
              {%- if v is mapping -%}
                {{ recurse(v, current_path ~ '.') }}
              {%- else -%}
                {{ output.append({'path': current_path, 'value': v}) }}
              {%- endif -%}
            {%- endfor -%}
          {%- endmacro -%}
          {%- set _ = recurse(my_vars) -%}
          {{ output }}
      vars:
        my_vars: "{{ vars | dict2items | selectattr('key', 'in', ['name', 'surname', 'address', 'contact']) | items2dict }}"

    - name: Print all paths and values
      debug:
        msg: "{{ item.path }}: {{ item.value }}"
      loop: "{{ recursive_items }}"

方法2:使用递归任务调用

通过include_tasks实现递归遍历,适合复杂嵌套场景:

  1. 创建recurse.yaml任务文件:
- name: Recurse into nested dict
  include_tasks: recurse.yaml
  loop: "{{ current_dict | dict2items }}"
  vars:
    current_path: "{{ current_path ~ item.key ~ '.' }}"
    current_dict: "{{ item.value }}"
  when: item.value is mapping

- name: Print leaf node key-value
  debug:
    msg: "{{ current_path ~ item.key }}: {{ item.value }}"
  loop: "{{ current_dict | dict2items }}"
  when: item.value is not mapping
  1. 主Playbook(list.yaml):
- name: Recursively print key-value paths
  hosts: localhost
  vars_files:
    - input.yaml
  tasks:
    - name: Start recursive traversal
      include_tasks: recurse.yaml
      loop: "{{ my_vars | dict2items }}"
      vars:
        current_path: ""
        current_dict: "{{ item.value }}"
      vars:
        my_vars: "{{ vars | dict2items | selectattr('key', 'in', ['name', 'surname', 'address', 'contact']) | items2dict }}"

说明

两种方法核心都是通过is mapping判断是否为嵌套字典,递归遍历直到叶节点,同时动态拼接完整路径,避免硬编码嵌套路径导致的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:39:56