繁体   English   中英

在 Ansible/Jinja2 中格式化项目列表

[英]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 joinregex_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM