使用字符串包含测试的 Jinja2 过滤器列表

使用字符串包含测试的 Jinja2 过滤器列表

问题描述:

当元素包含字符串时,我试图在 Jinja2 中的 ansible 中过滤列表,但 Jinja 文档似乎不够清晰,我无法弄清楚.

I'm trying to filter a list in ansible in Jinja2 when the elements contain a string, but the Jinja documentation doesn't seem clear enough for me to figure it out.

这是我目前所拥有的:

- name: run script
  command: /usr/tmp/run_script.py
  register: script_results

- name: display run info
  debug:
    var: "{{script_results.stdout_lines | select(\"'running script' in script_results.stdout_lines\") }}"

但我得到的只是错误:

"<generator object _select_or_reject at 0x13851e0>": "VARIABLE IS NOT DEFINED!"

例如,如果 stdout_lines 包含 ["apples","running script one","oranges","running script two"],我想打印

So for example, if stdout_lines contains ["apples","running script one","oranges","running script two"], I want to print

running script one
running script two

他们有文档选择内置测试文档,但它们不显示in"测试,我不知道它们在这个 ansible 变量的上下文中是如何工作的.

They have documentation for select and documentation for built-in-tests, but they don't display the "in" test, and I don't know how they work in the context of this ansible variable.

我试着这样解决:

- name: display run info
  debug:
    var: item
  with_items: "{{script_results.stdout_lines}}"
  when: "'running script' in item"

但是对于没有通过测试的每一行都显示跳过"......有点违背目的!

But that displays "skipping" for every line that doesn't pass the test ... kinda defeating the purpose!

select 过滤器将采用另一个过滤器.就像在文档 odd 中一样,它只会返回列表的奇数元素.您希望与 select 结合的过滤器是 equalto.

The select filter would take another filter. Like in the docs odd, which will return only the odd elements of the list. The filter you would like to combine select with is equalto.

现在事情来了.Ansible 捆绑了一个非常旧的 Jinja2 版本,它根本不包含 equalto 过滤器.是的,除非您想过滤奇数元素,否则它会变得毫无用处.(历史上从来没有人想要...)

Now here's the thing. Ansible bundles a very old version of Jinja2, which simply does not contain the equalto filter. Yes, that renders it useless unless you want to filter odd elements. (Which nobody ever in history wanted to...)

此外,我还无法使自定义过滤器插件在 Ansible 2 中工作.因此,您几乎被迫一起破解一些丑陋的东西.

Furthermore I was yet unable to make custom filter plugins work in Ansible 2. So you're pretty much forced to hack something ugly together.

helloV 已经显示了一个选项.这是另一个想法:

helloV already showed one option. Here is another idea:

- name: run script
  shell: /usr/tmp/run_script.py | grep "running script"
  register: script_results

更新:

我最近发现您可以将 match(不是标准的 Jinja2 过滤器,而是由 Ansible 添加)与 select 一起使用.这是 eualto 过滤器的一个很好的替代品,而且您可以使用正则表达式.这应该有效:

I recently discovered you can use match (not a standard Jinja2 filter but added by Ansible) together with select. Thats a good replacement for the eualto filter plus you can use regular expressions. This should work:

{{ script_results.stdout_lines | select("match", ".*running script.*") }}