如何附加到字符串列表中的每个项目?

时间:2015-11-09 19:29:09

标签: jinja2 salt-stack

我有一个包含IP地址的字符串列表。我想为每个人添加一个端口号。在python中,我会这样做:

df.CEEB

...但Jinja不支持列表理解。目前,我正在通过一次建立一个新项目列表来解决问题:

list()

这在模板中间是丑陋和恼人的,感觉应该有更好的方法来完成工作。优选单线。

虽然我知道这可以通过自定义过滤器来完成,但我正在为我没有编写的软件(saltstack)提供模板,所以它们(据我所知)对我来说是不可用的。

5 个答案:

答案 0 :(得分:2)

我对 ansible 的建议:

magic() | map('regex_replace', '$', ':'~port) | list

地图:将过滤器regex_replace应用于每个列表元素(如listElement | replace('$', ':'~port)
replace:将字符串的末尾替换为:和端口(将其附加)
list:将生成器转换为列表

使用正则表达式是一个过大的杀伤力,但是我的其他尝试甚至更多。不幸的是regex_replace确实not exist in normal jinja

答案 1 :(得分:2)

我一直使用的方法是使用 zip_longest 在字符串列表中创建列表,然后加入它们。

ip_string_list | zip_longest([], fillvalue='some_port') | map('join') | list

当然,如果您在变量中有端口,您可以这样做:

ip_string_list | zip_longest([], fillvalue=port_string) | map('join') | list

您也可以在 join 操作中包含分隔符:

ip_string_list | zip_longest([], fillvalue=port_string) | map('join', ':') | list

要在 reverse 中添加 throw:

ip_string_list | zip_longest([], fillvalue=port_string) | map('reverse') | map('join', ':') | list

我一直使用这种模式来构建 LDAP 专有名称。

编辑:这是我在 Ansible 中的做法,zip_longest 没有现货 Jinja2

答案 2 :(得分:1)

没有任何语言的列表理解令人讨厌!

您可以使用“| format”过滤器吗?

{% for ip in magic() -%}
curl_host_port:
  cmd.run:
    - name: {{ "curl 'http://%s:80/'"|format(ip) }}
{% endfor -%}

答案 3 :(得分:1)

这绝不是很漂亮,但这对我有用。我需要使用"!"来构建一个用户名列表。在每一个面前。此列表必须放在用户之间用逗号连接的行上。

我的用户列表(在vars,默认值或其他内容中设置)如下所示:

excluded_users: ["fred","jim","bob","arthur"]

在我的模板中我得到了这个:

Match user *,!root{% if excluded_users|length > 0 %},!{{ excluded_users|join(",!") }}{% endif %}

...一旦渲染并保存,它看起来像这样:

Match user *,!root,!fred,!jim,!bob,!arthur

就像我说的,不是特别漂亮; - )

答案 4 :(得分:0)

只需在列表项上进行迭代,然后使用jinja2来打印这样的元素:

   - set_fact:
        list_ip: "{% for ip in ip_list %}{{ip}}:{{port}}{% if not loop.last %},{% endif %}{% endfor %}"

并且lisp_ip vars将用逗号分隔您的字符串ip:port。然后您可以将其拆分以获得列表

lisp_ip.split(',')