【问题标题】:How to manipulate a list of dictionaries in Ansible?如何在 Ansible 中操作字典列表?
【发布时间】:2022-01-06 07:43:18
【问题描述】:

有一个字典列表如下图:

"test_list_of_dicts": [
{
  "inner_dict":[
    {"f1":"a","f2":"b"},
    {"f1":"c","f2":"d"}
  ],
  "id":"id1"
},
{
  "inner_dict":[
    {"f1":"e","f2":"f"},
    {"f1":"g","f2":"h"}
  ],
  "id":"id2"
}
]

我需要修改上面的结构并获得一个新的字典列表,如下所示:

"new_list_of_dicts": [
    {"f1":"a","f2":"b","id":"id1"},
    {"f1":"c","f2":"d","id":"id1"},
    {"f1":"e","f2":"f","id":"id2"},
    {"f1":"g","f2":"h","id":"id2"}
]

我找不到在 Ansible 中实现此目的的方法。

【问题讨论】:

    标签: ansible yaml jinja2


    【解决方案1】:

    例如

        - set_fact:
            new_list_of_dicts: "{{ new_list_of_dicts|d([]) + [item|combine] }}"
          with_subelements:
            - "{{ test_list_of_dicts }}"
            - inner_dict
    

    给予

      new_list_of_dicts:
        [
            {
                "f1": "a",
                "f2": "b",
                "id": "id1"
            },
            {
                "f1": "c",
                "f2": "d",
                "id": "id1"
            },
            {
                "f1": "e",
                "f2": "f",
                "id": "id2"
            },
            {
                "f1": "g",
                "f2": "h",
                "id": "id2"
            }
        ]
    

    参见with_subelementssubelements

    【讨论】:

    • 该建议有效并产生了预期的结果。谢谢。
    • 考虑@Zeitounator 的单线。如果你愿意,你也可以在任务之外使用它并使代码更简洁。
    【解决方案2】:

    基本上与@vladimir 的答案相同,但不需要循环:

    - name: manipulate dict
      hosts: localhost
      gather_facts: false
    
      vars:
        # Your var definition on a single line for legibility
        test_list_of_dicts: [{"inner_dict":[{"f1":"a","f2":"b"},{"f1":"c","f2":"d"}],"id":"id1"},{"inner_dict":[{"f1":"e","f2":"f"},{"f1":"g","f2":"h"}],"id":"id2"}]
    
        new_list_of_dicts: "{{ lookup('subelements', test_list_of_dicts, 'inner_dict')
          | map('combine') | list }}"
    
      tasks:
        - name: Show result
          debug:
            var: new_list_of_dicts
    

    同样给予:

    PLAY [manipulate dict] *****************************************************************************************************************************************************************************************************************
    
    TASK [show result] *********************************************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "new_list_of_dicts": [
            {
                "f1": "a",
                "f2": "b",
                "id": "id1"
            },
            {
                "f1": "c",
                "f2": "d",
                "id": "id1"
            },
            {
                "f1": "e",
                "f2": "f",
                "id": "id2"
            },
            {
                "f1": "g",
                "f2": "h",
                "id": "id2"
            }
        ]
    }
    
    PLAY RECAP *****************************************************************************************************************************************************************************************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
    

    【讨论】:

    • 我认为任务中的变量名称应该是“new_list_of_dicts”。当我使用这个建议时,我也得到了一个错误“”。这可能是由于语法问题,我不知道。无论如何,谢谢你的替代建议。
    • @Jai:您使用的是 ansible 2.9 或更早版本。我修复了该示例,使其也适用于您的版本(即在map 之后添加了list 过滤器)。修复了调试中的错字,输出是用正确的版本生成的。对不起,最后一个。
    猜你喜欢
    • 1970-01-01
    • 2021-07-20
    • 2019-01-29
    • 2018-05-10
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多