[英]Formatting a list of items in Ansible/Jinja2
是否可以使用 Ansible / Jinja2 中的格式化字符串将列表/字典列表转换为字符串列表?
我知道我可以做类似的事情:
{{["First: %d", "Second: %d"] | map("format", 1) | join(", ") }}
获得First: 1, Second 1
。
有没有可能做类似的事情
{{[[1, 1], [2, 2]] | map("format", "Num %d, %d") | join(", ") }}
并导致Num 1, 1, Num 2, 2
?
不,这是不可能的。 格式的参数反之亦然,例如
- debug:
msg: "{{ ['v1 %s', 'v2 %s']|map('format', 'XYZ')|list }}"
给
msg:
- v1 XYZ
- v2 XYZ
相反,可以 map join和regex_replace ,例如
- debug:
msg: "{{ _list|
map('join', ',')|
map('regex_replace', _regex, _replace)|
join(', ') }}"
vars:
_list: [[1,1],[2,2]]
_regex: '^(.*),(.*)$'
_replace: 'Num \1, \2'
做这项工作
msg: Num 1, 1, Num 2, 2
使用核心format
过滤器是不可能的。 但是如果你愿意写几行 python,你可以用自定义过滤器轻松解决这个问题。 我去了最简单的演示,您可能必须强化代码并修复边缘情况以供实际使用。 您可能想查看插件开发文档以获取更多信息。
对于此示例,我将自定义文件保存在与我的测试 playbook 相邻的filter_plugins
目录中。 如果您想在不同的项目之间共享,可以将其保存在集合或角色中。
在filter_plugins/my_format_filters.py
def reverse_format(param_list, format_string):
"""format format_sting using elements in param_list"""
return format_string % tuple(param_list)
class FilterModule(object):
"""my format filters."""
def filters(self):
"""Return the filter list."""
return {
'reverse_format': reverse_format
}
然后是以下示例剧本:
---
- name: custom filter demo
hosts: localhost
gather_facts: false
tasks:
- name: map custom reverse_format filter
debug:
msg: '{{ item.replacements | map("reverse_format", item.format) | join(", ") }}'
loop:
- replacements:
- [1, 1]
- [2, 2]
format: "Num %d, %d"
- replacements:
- ['Jack', 'John', 12]
- ['Mary', 'Alicia', 34]
format: "%s owes %s %d€"
给出:
PLAY [custom filter demo] **************************************************************************************************************************************************************************************************************
TASK [map custom reverse_format filter] ************************************************************************************************************************************************************************************************
ok: [localhost] => (item={'replacements': [[1, 1], [2, 2]], 'format': 'Num %d, %d'}) => {
"msg": "Num 1, 1, Num 2, 2"
}
ok: [localhost] => (item={'replacements': [['Jack', 'John', 12], ['Mary', 'Alicia', 34]], 'format': '%s owes %s %d€'}) => {
"msg": "Jack owes John 12€, Mary owes Alicia 34€"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在已经接受的答案的基础上,这里有一个版本,它还支持输入字典/对象列表:
class FilterModule(object):
"""my format filters."""
def filters(self):
"""Return the filter list."""
return {
'reverse_format': self.reverse_format
}
def reverse_format(self, value, format_string):
"""format format_sting using elements in param_list"""
return format_string.format(**value)
使用示例:
{{ hostvars.values() |
map('reverse_format', 'This is inventory host {inventory_hostname}!' |
join('\n') }}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.