Ansible regex_findall multiple sets
I was able to use with_list
instead of with_items
or with_nested
. Works fine now with list of lists. Referenced my other post: Ansible list of lists - flattening
variable within regex_findall in ansible
I tried the following method, it works fine.
- name: Get names for all running Oracle databases from oratab file
slurp:
src: /etc/oratab
register: oracle_patch_oratab
- name: "assign pattern"
set_fact:
ora_ver: "12201"
- name: Extract a list of DBs which mataches the Oracle Home
set_fact:
oracle_patch_dblist: "{{ oracle_patch_oratab['content'] | b64decode | regex_findall ('(.+' + ora_ver | string + '.+)', multiline=True, ignorecase=True) }}"
Ansible or Python, how to use regex_findall on a list to return words that start with a certain pattern
edit: updated with the new requirement
While Frenchy's answer isn't wrong, it will be inherently slower and is a lot more verbose than the way Jinja2 wants that done which is via the |select
filter, designed for working with list items:
- set_fact:
start_with_water: >-
{{ list1 | select('match', '^water')
| map('regex_findall', '([^ ]+) .*')
| map('first')
| list }}
produces
{
"ansible_facts": {
"start_with_water": [
"water_3gallons_6/20/22",
"water_1gal_today"
]
},
"changed": false
}
In case you were curious why your approach with regex_findall
did not do what you expected, it's because that filter wants a string input, so jinja2 helpfully(?) coerced the list[str]
into str
by calling str(list1)
and fed that into the filter which didn't match any "start of line" like you expected
Split a text to words with regex_findall
Map regex_findall, e.g.
- debug:
msg: "{{ lookup('file', 'mycongig.txt').splitlines()|
map('regex_findall', '[\\w\\.]+')|
list }}"
gives
msg:
- - key1
- 192.168.0.1
- - key2
- 192.168.0.2
- - key3
- 192.168.0.3
- - key4
- 192.168.0.4
How to use regex_findall in Ansible playbook properly?
It's helpful if you give a reproducible example. Here's one:
- hosts: localhost
connection: local
vars:
xyz: "hello"
tasks:
- debug:
msg: "{{ xyz | regex_findall('\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b') }}"
- debug: msg="done."
With -vvv
, I get a more descriptive error message:
exception type: <class 'yaml.scanner.ScannerError'>
exception: while scanning a double-quoted scalar
in "<unicode string>", line 7, column 12:
msg: "{{ xyz | regex_findall('\b(?:[0 ...
^
found unknown escape character '.'
in "<unicode string>", line 7, column 53:
... regex_findall('\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b') }}"
So my first guess seems to have fixed it- double-backslash the backslashes.
- hosts: localhost
connection: local
vars:
# xyz: "hello"
xyz: "1.2.3.4"
tasks:
- debug:
msg: "{{ xyz | regex_findall('\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b') }}"
- debug: msg="done."
Ansible: What is the correct syntax for a variable within a findall regex
You never nest Jinja {{...}}
template markers. Within a Jinja template, if you want to combine a literal string and a variable, you can use the ~
string concatenation operator, like this:
- debug: msg="{{ nodeId.content | regex_findall("(\w+-\w+-\w+-\w+-\w+)..<address>\d+\.\d+\.\d+\.\d+:?\d+?<\/address><name>" ~ the_name) }}"
The ~
operator is like +
, except it will convert arguments into
strings so that you can concatenate numeric values to a string
(writing "this " + 1
would fail, but "this " ~ 1
would work).
Or you can use Python string formatting syntax, like this:
- debug: msg="{{ nodeId.content | regex_findall("(\w+-\w+-\w+-\w+-\w+)..<address>\d+\.\d+\.\d+\.\d+:?\d+?<\/address><name>%s" % (the_name)) }}"
This syntax uses printf
-style formatting tokens (%s
for strings,%d
for integers, etc). Or like this:
- debug: msg="{{ nodeId.content | regex_findall("(\w+-\w+-\w+-\w+-\w+)..<address>\d+\.\d+\.\d+\.\d+:?\d+?<\/address><name>{}".format(the_name)) }}"
Here is one site that documents Python
string formatting in some detail.
Ansible regex_findall is not giving expected results with negative search
It's because that json_query
emits a list[str]
which when fed directly into regex_findall
doesn't become a newline delimited string, it becomes the same as str(["alpha", "beta"])
(e.g. ['alpha', 'beta']
) and then the multiline regex fails to do what you are expecting
There are, as with many things in life, a few ways to fix that. One is to just feed the results into |join("\n")
and then you're likely back where you thought you were to begin with:
- debug:
msg: "{{ jsonOutput | json_query('json.response.results[].dnsName') | join('\n') | regex_findall('(?![a-z]{3}[0-9]{2}v)^.*', multiline=true) }}"
The other is to acknowledge that it's a list[str]
and use the | select("match", ...)
filter to only allow though items that match:
- debug:
msg: >-
{{ response | json_query('results[].dnsName')
| select('match', '(?![a-z]{3}[0-9]{2}v)^.*')
| list }}
vars:
response:
results:
- dnsName: abc02vsomeserver01.subdomain1.domain.gov
- dnsName: abc02someserver01.subdomain1.domain.gov
- dnsName: xyz03votherserver11.subdomain2.domain.gov
- dnsName: wyz03otherserver11.subdomain2.domain.gov
- dnsName: qrsmainserver02.maindomain.domain.gov
similarly produces:
"msg": [
"abc02someserver01.subdomain1.domain.gov",
"wyz03otherserver11.subdomain2.domain.gov",
"qrsmainserver02.maindomain.domain.gov"
]
I would guess it's personal preference which style works best in your playbook
Related Topics
Wkwebview Origin Null Is Not Allowed by Access-Control-Allow-Origin
How to Load an Http Url With App Transport Security Enabled in iOS 9
Should Iboutlets Be Strong or Weak Under Arc
How to Hide Uinavigationbar 1Px Bottom Line
Uialertview Addsubview in Ios7
Xcode 4.2 Debug Doesn't Symbolicate Stack Call
How to Produce an Effect Similar to the iOS 7 Blur View
Detect Tap on a Button in Uitableviewcell for Uitableview Containing Multiple Sections
Set the Maximum Character Length of a Uitextfield
Ios App With Framework Crashed on Device, Dyld: Library Not Loaded, Xcode 6 Beta
How to Check When a Uitextfield Changes
Objective-C and Swift Url Encoding