Ansible:如何在变量中查找单词出现?
Ansible: How to find word occurrence in a variable?
我到处搜索如何为 Ansible 查找变量中出现的单词,但没有找到。我找到的最接近的方法是在变量中搜索任何 'word' 但它不计算那里有多少个单词并且只返回布尔值。这是我的剧本:
---
- 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')
这是inputFile.txt内容:
{"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"]}
这是上述剧本的结果:
有什么方法可以调整此脚本以满足我的目的吗?我需要计算变量中有多少个单词 'down' 。
我已经尝试使用 regex_findall 以及如下所示:
- 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"
如果用于普通字符串没问题,但在这种情况下我会收到模板错误,我不知道为什么:
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"}
$ 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 是一个变量,它没有stdout 属性,所以只是{{ output }},如果您有进一步的问题,请告诉我。
新的过滤器插件 community.general.counter
是解决您问题的另一种方法。它在 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"
}
我到处搜索如何为 Ansible 查找变量中出现的单词,但没有找到。我找到的最接近的方法是在变量中搜索任何 'word' 但它不计算那里有多少个单词并且只返回布尔值。这是我的剧本:
---
- 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')
这是inputFile.txt内容:
{"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"]}
这是上述剧本的结果:
有什么方法可以调整此脚本以满足我的目的吗?我需要计算变量中有多少个单词 'down' 。
我已经尝试使用 regex_findall 以及如下所示:
- 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"
如果用于普通字符串没问题,但在这种情况下我会收到模板错误,我不知道为什么:
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"}
$ 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 是一个变量,它没有stdout 属性,所以只是{{ output }},如果您有进一步的问题,请告诉我。
新的过滤器插件 community.general.counter
是解决您问题的另一种方法。它在 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"
}