逗号的 Jinja2 模板输出解析问题
Jinja2 template output parsing issue for comma
我已经为 ansible playbook 编写了 jinja2 模板。但是,出于这个原因,我不想在最后一行的末尾使用逗号,我已经将 "if" 条件与 "loop.last" 一起使用。由于存在 "for" 循环和 "if" 循环,所以最后一行执行了两次 - 一次带逗号,另一次不带逗号。如果最后一行不带逗号执行一次,我们将不胜感激。
[{% for ip in range %}
"127.0.0.1:{{ ip }}",
{% if loop.last %}
"127.0.0.1:{{ ip }}"
{% endif %}
{% endfor %}]
下面是我得到的输出,
[ "127.0.0.1:6000",
"127.0.0.1:6001",
"127.0.0.1:6002",
"127.0.0.1:6003",
"127.0.0.1:6004",
"127.0.0.1:6005",
"127.0.0.1:6006",
"127.0.0.1:6006"
]
预期输出:
["127.0.0.1:6000", "127.0.0.1:6001", "127.0.0.1:6002", "127.0.0.1:6003", "127.0.0.1:6004", "127.0.0.1:6005", "127.0.0.1:6006" ]
谢谢
您可以为非最后一次迭代添加一个 else
子句。试试这个模板文件:
[{% for ip in range %}
{% if loop.last %}
"127.0.0.1:{{ ip }}"{% else %}
"127.0.0.1:{{ ip }}", {% endif %}
{% endfor %}]
生成的文件:
[root@greenhat-30 tests]$ cat /tmp/test.out
["127.0.0.1:6001", "127.0.0.1:6002", "127.0.0.1:6003", "127.0.0.1:6004", "127.0.0.1:6005", "127.0.0.1:6006"]
[root@greenhat-30 tests]$
希望对您有所帮助
- 您应该格外小心您的 var 名称。
range
实际上是 jinja2 function,有时可能会导致错误。
- 您当前的问题基本上归结为通过添加前缀并将结果输出为 json 字符串来转换输入列表。
在下面的例子中:
- 最初的
range(6001,6007)
动态地用相同数量的值替换您当前的变量(例如)。您可以简单地将此函数替换为包含实际值列表的重命名变量(请参阅上面的第 1 点)。
- 我使用
regex_replace
filter with map
为列表中的每个值添加 127.0.0.1:
。
- 最后,我使用
to_json
filter 将列表输出为所需的格式。
最终模板:
{{ range(6001,6007) | map('regex_replace','^', '127.0.0.1:') | list | to_json }}
我们可以使用可靠的调试任务轻松测试它:
---
- name: Demo template
hosts : localhost
gather_facts: false
tasks:
- name: Add prefix to range list and output json
debug:
msg: "{{ range(6001,6007) | map('regex_replace','^', '127.0.0.1:') | list | to_json }}"
其中给出(注意:调试添加反斜杠以转义结果字符串中的双引号。结果模板中的实际输出将不包含它们。)
PLAY [Demo template] ****************************************************************************************************************************************************************************************************************************************************
TASK [Add prefix to range list and output json] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "[\"127.0.0.1:6001\", \"127.0.0.1:6002\", \"127.0.0.1:6003\", \"127.0.0.1:6004\", \"127.0.0.1:6005\", \"127.0.0.1:6006\"]"
}
PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我已经为 ansible playbook 编写了 jinja2 模板。但是,出于这个原因,我不想在最后一行的末尾使用逗号,我已经将 "if" 条件与 "loop.last" 一起使用。由于存在 "for" 循环和 "if" 循环,所以最后一行执行了两次 - 一次带逗号,另一次不带逗号。如果最后一行不带逗号执行一次,我们将不胜感激。
[{% for ip in range %}
"127.0.0.1:{{ ip }}",
{% if loop.last %}
"127.0.0.1:{{ ip }}"
{% endif %}
{% endfor %}]
下面是我得到的输出,
[ "127.0.0.1:6000",
"127.0.0.1:6001",
"127.0.0.1:6002",
"127.0.0.1:6003",
"127.0.0.1:6004",
"127.0.0.1:6005",
"127.0.0.1:6006",
"127.0.0.1:6006"
]
预期输出:
["127.0.0.1:6000", "127.0.0.1:6001", "127.0.0.1:6002", "127.0.0.1:6003", "127.0.0.1:6004", "127.0.0.1:6005", "127.0.0.1:6006" ]
谢谢
您可以为非最后一次迭代添加一个 else
子句。试试这个模板文件:
[{% for ip in range %}
{% if loop.last %}
"127.0.0.1:{{ ip }}"{% else %}
"127.0.0.1:{{ ip }}", {% endif %}
{% endfor %}]
生成的文件:
[root@greenhat-30 tests]$ cat /tmp/test.out
["127.0.0.1:6001", "127.0.0.1:6002", "127.0.0.1:6003", "127.0.0.1:6004", "127.0.0.1:6005", "127.0.0.1:6006"]
[root@greenhat-30 tests]$
希望对您有所帮助
- 您应该格外小心您的 var 名称。
range
实际上是 jinja2 function,有时可能会导致错误。 - 您当前的问题基本上归结为通过添加前缀并将结果输出为 json 字符串来转换输入列表。
在下面的例子中:
- 最初的
range(6001,6007)
动态地用相同数量的值替换您当前的变量(例如)。您可以简单地将此函数替换为包含实际值列表的重命名变量(请参阅上面的第 1 点)。 - 我使用
regex_replace
filter withmap
为列表中的每个值添加127.0.0.1:
。 - 最后,我使用
to_json
filter 将列表输出为所需的格式。
最终模板:
{{ range(6001,6007) | map('regex_replace','^', '127.0.0.1:') | list | to_json }}
我们可以使用可靠的调试任务轻松测试它:
---
- name: Demo template
hosts : localhost
gather_facts: false
tasks:
- name: Add prefix to range list and output json
debug:
msg: "{{ range(6001,6007) | map('regex_replace','^', '127.0.0.1:') | list | to_json }}"
其中给出(注意:调试添加反斜杠以转义结果字符串中的双引号。结果模板中的实际输出将不包含它们。)
PLAY [Demo template] ****************************************************************************************************************************************************************************************************************************************************
TASK [Add prefix to range list and output json] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "[\"127.0.0.1:6001\", \"127.0.0.1:6002\", \"127.0.0.1:6003\", \"127.0.0.1:6004\", \"127.0.0.1:6005\", \"127.0.0.1:6006\"]"
}
PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0