我有以下词典列表:
"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 并不是一个很好的数据操作工具。对于您想要做的事情,最简单的解决方案可能是用 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"
}
]
}
这里介绍的过滤器比它需要的稍微复杂一些,因为它支持任意属性的查找/替换。
过滤基本名称并创建字典列表
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