Reputation: 47
I have this list:
ok: [localhost] => {
"ansible_facts": {
"servs": [
"Is active: Yes\nHost Name: northrend\n Ip Address: 192.168.1.12",
"Is active: Yes\nHost Name: pandaria \n IP Address: 192.168.1.30"
]
},
I've been trying to parse this list to extract the value of "Host name" but I just keep on getting the following error:
fatal: [localhost]: FAILED! => {
"msg": "Unexpected templating type error occurred on ({{ servs | regex_search('Host Name: (.)+\n'),multiline=True) }}): expected string or buffer"
}
This is what I tried:
- set_fact:
output: {{ servs | regex_search('Host Name: (.)+\n'), multiline=True) }}
How do you properly parse the contents of this list?
Upvotes: 2
Views: 1263
Reputation: 68144
The list servs is nearly valid YAML. Only the indentation of the attribute 'Ip Address' is wrong. One space shifted to the right. If you manage to get rid of this space, e.g.
servs:
- "Is active: Yes\nHost Name: northrend\nIp Address: 192.168.1.12"
- "Is active: Yes\nHost Name: pandaria \nIP Address: 192.168.1.30"
the situation would be trivial. Simply convert the list of strings to a list of dictionaries, e.g.
- set_fact:
servs_list: "{{ servs_list|d([]) + [item|from_yaml] }}"
loop: "{{ servs }}"
gives
servs_list:
- Host Name: northrend
Ip Address: 192.168.1.12
Is active: true
- Host Name: pandaria
IP Address: 192.168.1.30
Is active: true
If you can't fix the indentation parse the data on your own. The task below gives the same result
- set_fact:
servs_list: "{{ servs_list|d([]) + [item|
regex_replace(regex, replace)|
from_yaml] }}"
loop: "{{ servs }}"
vars:
regex: '\n '
replace: '\n'
Get the output
- set_fact:
output: "{{ servs_list|map(attribute='Host Name')|list }}"
gives
output:
- northrend
- Pandaria
Upvotes: 1
Reputation: 4564
You have multiple errors here:
regex_search
works on strings, not lists. So you need to apply it to each list element.(.+)
.Host Name:
) and not just the name itself. You need to specify which matching group to return.I guess the list is from the output of some script or in some file. It would be a lot better to have it as json
or yaml
and then use from_json
or from_yaml
.
If you want to keep it like that, you need to do this:
- hosts: all
vars:
servs:
- |
Is active: Yes
Host Name: northrend
Ip Address: 192.168.1.12
- |
Is active: Yes
Host Name: pandaria
IP Address: 192.168.1.30
tasks:
- debug:
msg: "{{ servs }}"
- set_fact:
output: "{{ servs | map('regex_search', 'Host Name: (.+)\n', '\\1') | list }}"
- debug:
msg: "{{ output }}"
This is the output:
TASK [debug] ************
ok: [local] => {
"msg": [
"Is active: Yes\nHost Name: northrend\nIp Address: 192.168.1.12\n",
"Is active: Yes\nHost Name: pandaria\nIP Address: 192.168.1.30\n"
]
}
TASK [set_fact] ***************
ok: [local]
TASK [debug] ************
ok: [local] => {
"msg": [
[
"northrend"
],
[
"pandaria"
]
]
}
Upvotes: 1