Jinja2 filter list using string contains test

I'm trying to filter a list out of reach of Jinja2 when the elements contain a string, but the Jinja documentation does not seem clear enough to me to understand it.

This is what I have so far:

- 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\") }}" 

But all I get is the error:

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

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 

They have documentation for selection 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 mutable variable.

I tried to solve it like this:

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

But this displays β€œgaps” for every line that fails the test ... seemingly defeating the target!

+6
source share
4 answers

The select filter will accept another filter. Like in docs odd , which will return only odd list items. The filter you would like to combine select with equalto .

Now here's the thing. Ansible integrates a very old version of Jinja2, which simply does not contain an equalto filter. Yes, this makes it useless if you don't want to filter the odd elements. (Who never in history wanted ...)

In addition, I have not yet been able to create custom filter plugins in Ansible 2. Thus, you are pretty much forced to hack something ugly together.

helloV has already shown one option. Here is another idea:

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

Update:

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

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

I understand that there can be several ways to do this. Will this work for you?

  - debug: var={{item}} when: item.find('running script') > -1 with_items: script_results.stdout_lines 
+4
source

I ended up writing a python script to do this because I could not get the available or ancient jinja2 to make the cut.

Possible tasks:

 - name: gather run info command: "{{role_path}}/files/print_results.py {{script_results.stdout_lines}}" register: script_print_results delegate_to: 127.0.0.1 run_once: true - name: display run info debug: var: script_print_results.stdout_lines delegate_to: 127.0.0.1 run_once: true 

Python script:

 for result_line in sys.argv[1:]: if "running script:" in result_line: print result_line[1:-1] 
0
source

You can create a new list with set_fact and print the elements of the new list.

 - hosts: localhost gather_facts: false vars: script_stdout_lines: - apples - running script one - oranges - running script two tasks: - set_fact: new_list: "{{ new_list | default([]) + [item] }}" with_items: "{{ script_stdout_lines }}" when: '"running script" in item' - debug: var=new_list 

Result:

 TASK [set_fact] ********************************************************************************************************************* skipping: [localhost] => (item=apples) ok: [localhost] => (item=running script one) skipping: [localhost] => (item=oranges) ok: [localhost] => (item=running script two) TASK [debug] ************************************************************************************************************************ ok: [localhost] => { "new_list": [ "running script one", "running script two" ] } 

It prints skipping in the set_fact operation set_fact but at the end it provides a new list with the only matching elements.

0
source

Source: https://habr.com/ru/post/1242575/


All Articles