如何从一个值和一个值列表构建一个字符串?

How can I build a string from a value and a list of values?

[第一次提问。我 认为 我已将其定位为 Ansible 问题。如果没有,欢迎温和的重定向!]

鉴于:

gid: 80
ports: [80, 443]

其中端口的数量可能从 0 到很多不等

我想生成这样的字符串:

"gid:80:tcp:80,gid:80:tcp:443"

(恰好是 FreeBSD mac_portacl 规则字符串)

我得到的最远的是:

portacl_rules: "{{ ports | zip_longest([], fillvalue='80') | list }}"

这给了我这样的东西:

    "msg": [
        [
            80,
            "80"
        ],
        [
            443,
            "80"
        ]
    ]

但是:

我可以创建 gid 字符串,gid:80 通过定义一个临时变量:

gid: 80
_tmp_gid: "gid:{{ gid }}"

但是由于我无法将字符串插入到填充值中,所以我被卡住了。

我在 format 过滤器周围胡闹,但它似乎将输出字符串作为其输入并将值作为其参数,这与我的情况相反。

有什么建议吗?

如果你不介意一对 set_fact 任务,你可以这样做:

- set_fact:
    rules_list: "{{ rules_list|default([]) + ['gid:{}:tcp:{}'.format(gid, item)] }}"
  loop: "{{ ports }}"

- set_fact:
    rules_str_1: "{{ ','.join(rules_list) }}"

- debug:
    var: rules_str_1

第一个任务创建以下形式的列表:

[
  "gid:80:tcp:80",
  "gid:80:tcp:443"
]

第二个任务使用 , 连接这些项目。

您可以使用涉及 regex_replace 过滤器的稍微复杂的表达式在单个操作中完成该操作:

- set_fact:
    rules_str_2: '{{ ",".join(ports|map("regex_replace", "^(.*)$", "gid:{}:tcp:".format(gid))) }}'

- debug:
    var: rules_str_2

要使 set_fact 任务按书面方式工作,您 必须 在外部使用单引号(这禁止使用 \ 作为转义符特点)。你可以交换引号,但是你需要写 \ 而不是 \。回想一下,匹配表达式中的 (...) 创建了一个捕获组,替换字符串中的 </code> 扩展为第一个捕获组的值。</p> <hr> <p>将所有内容放在剧本中:</p> <pre><code>--- - hosts: localhost gather_facts: false vars: gid: 80 ports: [80, 443] tasks: - set_fact: rules_list: "{{ rules_list|default([]) + ['gid:{}:tcp:{}'.format(gid, item)] }}" loop: "{{ ports }}" - set_fact: rules_str_1: "{{ ','.join(rules_list) }}" - debug: var: rules_str_1 - set_fact: rules_str_2: '{{ ",".join(ports|map("regex_replace", "(.*)", "gid:{}:tcp:".format(gid))) }}' - debug: var: rules_str_2

这将产生以下输出:

PLAY [localhost] ******************************************************************************************************************************************************************************

TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=80)
ok: [localhost] => (item=443)

TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "rules_str_1": "gid:80:tcp:80,gid:80:tcp:443"
}

TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "rules_str_2": "gid:80:tcp:80,gid:80:tcp:443"
}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0