2

I have searched everywhere on how to find the word occurrence in variable for Ansible but not found. The closest way I found is by searching any 'word' in a variable but it does not count how many words are there and only returning boolean value. Here is my playbook:

---

- hosts: localhost
  name: Test Variable Manipulation and Searching
  gather_facts: false
  tasks:
    - name: read the Output File
      set_fact: 
        output: "{{lookup('file', 'inputFile.txt') }}"

    - name: debug the input file
      debug:
        msg: "{{output.stdout}}"

    - name: find word 'down'
      debug:
        msg: "Found the word 'down' in the Variables/Output"
      when: output.stdout is search('down')  

This is the inputFile.txt content:

{"failed": false, "changed": false, "ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "stdout_lines": [["Gi1/0/14                       down           down"]], "stdout": ["Gi1/0/14                       down           down"]}

This is the result of the above playbook: The playbook result

Is there any way I can tweak this script to meet my purpose? I need to count how many word 'down' from the variable.

I have tried using regex_findall as well as shown below:

      - name: check the down Status if EQUAL to 2
      block:
        - name: check the down Status if EQUAL to 2
          debug:
            msg: "Both Status is down. Check is clear"
          when: (output.stdout|regex_findall('down')|length) == 2
      rescue:
        - debug:
            msg: "Unable to use the regex_findall to desResult" 

It is fine if used towards normal String but I will get templating error for this case and i dont know why:

fatal: [localhost]: FAILED! => {"msg": "The conditional check '(output.stdout|regex_findall('down')|length) == 2' failed. The error was: Unexpected templating type error occurred on ({% if (output.stdout|regex_findall('down')|length) == 2 %} True {% else %} False {% endif %}): expected string or bytes-like object\n\nThe error appears to be in 'switchCheck.yml': line 17, column 11, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n      block:\n        - name: check the down Status if EQUAL to 2\n          ^ here\n"}

Fitri Izuan
  • 350
  • 1
  • 6
  • 18

2 Answers2

5
$ cat test.yml
- hosts: localhost
  name: Test Variable Manipulation and Searching
  gather_facts: false
  tasks:
    - name: read the Output File
      set_fact:
        output: "{{lookup('file', 'inputFile.txt') }}"

    - name: debug the input file
      debug:
        msg: "{{ output | regex_findall('down') | length }}"
      when: (output | regex_findall('down') | length) == 3

$ cat inputFile.txt
Gi1/0/14 down down go down

output is an variable, it does not have the attribute stdout, so just {{ output }}, if you have further questions, please let me know.

Z.Liu
  • 403
  • 2
  • 9
  • 1
    Hi, thank you for your answer. The inputFile.txt did have the stdout. Even without using the stdout also have the same templating error. I have edited the post to include more details. The content of the txt file is not as what u have assumed. – Fitri Izuan Apr 22 '20 at 04:39
  • @FitriIzuan I see, from the error you got, it says regex_findall need a string string or bytes-like object, but "{{ output.stdout }}" is a list, so you need to use "{{ output.stdout[0] | regex_findall('down') | length }}". – Z.Liu Apr 22 '20 at 05:05
0

The new filter plugin community.general.counter is another way to solve your problem. It's available in ansible>=5.2

$ pip freeze | grep ansible
ansible==5.4.0
ansible-core==2.12.2

$ cat test.yml
---
- hosts: localhost
  gather_facts: false
  tasks:
    - name: word occurence in string
      set_fact:
        counter: "{{ lookup('file', 'inputFile.txt') | split | community.general.counter }}"

    - debug:
        var: counter

    - debug:
        msg: "{{ counter['down'] }}"


$ ansible-playbook test.yml
PLAY [localhost] **********************

TASK [word occurence in string] *******
ok: [localhost]

TASK [debug] **************************
ok: [localhost] => {
    "counter": {
        "Gi1/0/14": 1,
        "down": 2
    }
}

TASK [debug] **************************
ok: [localhost] => {
    "msg": "2"
}

filter documentation

keilr
  • 1