Ansible:更新字典列表中的值

问题描述 投票:0回答:2

我有以下词典列表:

"errorlist": [
    {
        "error": "Not found",
        "path": "/tmp/working/directory1/file1"
    },
    {
        "error": "Not found",
        "path": "/tmp/working/directory2/file1"
    },
    {
        "error": "Not found",
        "path": "/tmp/working/directory1/file2"
    },
    {
        "error": "Not found",
        "path": "/tmp/working/directory2/file2"
    }
]

我想删除路径值的“/tmp/working/”部分,即。将绝对路径转换为相对路径。

我在网上搜索时也遇到过类似的问题,但没有找到解决方案。它应该相当简单,但我无法理解它。

预期结果应该是具有更新值的原始列表或具有相同结构的新列表。

ansible
2个回答
0
投票

Ansible 并不是一个很好的数据操作工具。对于您想要做的事情,最简单的解决方案可能是用 Python 编写的自定义过滤器。将以下内容放入

filter_plugins/filters.py
(其中
filter_plugins
目录与您的剧本位于同一目录中):

def replaceInAttribute(data, attr, find, replace):
    for d in data:
        if attr in d:
            d[attr] = d[attr].replace(find, replace)

    return data


class FilterModule:
    def filters(self):
        return {
            "replaceInAttribute": replaceInAttribute,
        }

现在你可以编写这样的剧本:

- hosts: localhost
  gather_facts: false
  vars:
    errorlist: [
        {
            "error": "Not found",
            "path": "/tmp/working/directory1/file1"
        },
        {
            "error": "Not found",
            "path": "/tmp/working/directory2/file1"
        },
        {
            "error": "Not found",
            "path": "/tmp/working/directory1/file2"
        },
        {
            "error": "Not found",
            "path": "/tmp/working/directory2/file2"
        }
    ]
  tasks:
  - debug:
      msg: "{{ errorlist | replaceInAttribute('path', '/tmp/working/', '') }}"

并得到这个输出:

TASK [debug] *************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "error": "Not found",
            "path": "directory1/file1"
        },
        {
            "error": "Not found",
            "path": "directory2/file1"
        },
        {
            "error": "Not found",
            "path": "directory1/file2"
        },
        {
            "error": "Not found",
            "path": "directory2/file2"
        }
    ]
}

这里介绍的过滤器比它需要的稍微复杂一些,因为它支持任意属性的查找/替换。


0
投票

过滤基本名称并创建字典列表

  paths: "{{ errorlist | map(attribute='path') | map('basename') |
                         map('community.general.dict_kv', 'path') }}"

给予

  paths:
    - {path: file1}
    - {path: file1}
    - {path: file2}
    - {path: file2}

压缩列表并合并项目

  result: "{{ errorlist | zip(paths) | map('combine') }}"

给你想要的

  result:
    - {error: Not found, path: file1}
    - {error: Not found, path: file1}
    - {error: Not found, path: file2}
    - {error: Not found, path: file2}

用于测试的完整剧本示例

- hosts: localhost

  vars:

    errorlist:
      - {error: Not found, path: /tmp/working/directory1/file1}
      - {error: Not found, path: /tmp/working/directory2/file1}
      - {error: Not found, path: /tmp/working/directory1/file2}
      - {error: Not found, path: /tmp/working/directory2/file2}

    paths: "{{ errorlist | map(attribute='path') | map('basename') |
                           map('community.general.dict_kv', 'path') }}"
    result: "{{ errorlist | zip(paths) | map('combine') }}"

  tasks:

    - debug:
        var: paths | to_yaml
    - debug:
        var: result | to_yaml
© www.soinside.com 2019 - 2024. All rights reserved.