Jinja2 filter list using string contains test

后端 未结 4 1566
遥遥无期
遥遥无期 2021-02-20 06:01

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.

Thi

相关标签:
4条回答
  • 2021-02-20 06:08

    I understand there may be more than one way to do this. Will this work for you?

      - debug: var={{item}}
        when: item.find('running script') > -1
        with_items: script_results.stdout_lines
    
    0 讨论(0)
  • 2021-02-20 06:13

    You can build a new list with set_fact and print the elements of a 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 during set_fact operation but at the end it provides a new list with the only matching items.

    0 讨论(0)
  • 2021-02-20 06:21

    I ended up writing a python script to do it, because I couldn't get ansible or ancient-jinja2 to make the cut.

    Ansible 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 讨论(0)
  • 2021-02-20 06:33

    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.

    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...)

    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 already showed 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 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.*") }}
    
    0 讨论(0)
提交回复
热议问题