Ansible 如何从值和值列表构建字符串?
[第一次提问者。我想我把这个问题定位为一个可回答的问题。如果不是,欢迎温和的重定向!] 鉴于:Ansible 如何从值和值列表构建字符串?,ansible,ansible-template,Ansible,Ansible Template,[第一次提问者。我想我把这个问题定位为一个可回答的问题。如果不是,欢迎温和的重定向!] 鉴于: gid: 80 ports: [80, 443] 其中端口数可能从0到多个不等 我想制作一个如下的字符串: "msg": [ [ 80, "80" ], [ 443, "80" ] ] - set_fact: rul
gid: 80
ports: [80, 443]
其中端口数可能从0到多个不等
我想制作一个如下的字符串:
"msg": [
[
80,
"80"
],
[
443,
"80"
]
]
- 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
(正好是FreeBSD mac_portacl规则字符串)
我得到的最远信息是:
portacl_rules: "{{ ports | zip_longest([], fillvalue='80') | list }}"
这给了我这样的感觉:
"msg": [
[
80,
"80"
],
[
443,
"80"
]
]
- 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是硬编码的,我不知道如何插值变量值;及
- 我无法将列表转换为最终字符串
gid:80
:
gid: 80
_tmp_gid: "gid:{{ gid }}"
但是因为我不能在fillvalue中插入字符串,所以我被卡住了
我对格式
过滤器进行了修改,但它似乎将输出字符串作为输入,将值作为参数,这与我的情况相反
有什么建议吗?如果您不介意一对
set\u fact
任务,您可以这样做:
"msg": [
[
80,
"80"
],
[
443,
"80"
]
]
- 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\u replace
过滤器:
- set_fact:
rules_str_2: '{{ ",".join(ports|map("regex_replace", "^(.*)$", "gid:{}:tcp:\1".format(gid))) }}'
- debug:
var: rules_str_2
要使该设置\u fact
任务按编写的方式工作,必须在外部使用单引号(这禁止将\
用作转义字符)。你可以交换引号,但是你需要写\\
,而不是\
。回想一下,匹配表达式中的(…)
创建了一个捕获组,替换字符串中的\1
扩展为第一个捕获组的值
将所有这些放在一个剧本中:
---
- 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:\1".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
谢谢你的解决方案。两步回答有效,但一步不行(在我手里…),它给出了“规则”——“gid:80:tcp:80gid:80:tcp:,gid:80:tcp:443gid:80:tcp:,gid:80:tcp:987gid:80:tcp:”。我不知道如何做一个包含所有信息的更长的回复…请参阅我的评论和我的原始问题,两步版本有效,单步版本不适用于我。请尝试更新的版本(我必须锚定正则表达式,因此它现在读作
^(.*$
)。啊,我明白了。您编辑了这篇散文,但“将其全部放在剧本中”示例仍然包含旧版本(这就是我剪切和粘贴的内容)。使用锚定的regexp,效果非常好。再次感谢!!!