Ansible Automation is really powerful with its filters and functions. It does provide various string manipulation and formatting filters from Jinja and Python.
In this article, we are going to see how to Split strings in Ansible.
As you might have already guessed, Ansible provides filters/functions to ease our job.
Ansible split is a filter based on Python Split to split based on a character (separator)
We will see examples of Ansible Split filters with different datasets like Simple strings, Lists, Dictionaries etc.
Ansible Split Examples
When it comes to string formatting, Splitting the string into multiple parts based on the separator position has always been a key element.
Let's say you have a CSV file and you want to convert the CSV(comma separated values) into a list of values like sequence or array like this
sarav,9876543210,[email protected] =>to=> ['sarav','9876543210','[email protected]']
Now you can simply use their index value to get the value like name, mobile or email id
Or let's imagine you have a lot of business email IDs and you are interested in only the domain names
[email protected] [email protected] [email protected] [email protected]
With python, you can simply do it like this
Let us see how to do the same with Ansible now.
Not just one, There are multiple ways to do this in Ansible. here is one more
Let us go through the source code of these items and much more, to understand the Ansible Split filter better.
Quick Note on Supported Ansible Versions:
Ansible Split is a Jinja2 Filter and Legacy Ansible versions do not support Jinja2 and Jinja3 filters.
I recommend you to update the Ansible version if you are getting the following error
no filter named 'split'
I have used Ansible 2.10+ for testing all these Split filters.
Example1: Ansible Split Simple String
Splitting a simple string in Ansible with a Split filter is no big job.
All you need to use is a simple split followed by the string. Here is a quick example
---
- name: Ansible Split Examples
hosts: localhost
tasks:
- name: Split Simple String Example
debug: msg={{ '[email protected]'|split('@')}}
Here is the execution and the output
I know this is a really simple example. Move on to some real-time examples down below.
Example2: Ansible Split with loop - To process list of strings
In this example, we have a list of email IDs stored in a variable called emails which is being sent to the loop iteration
For those who are familiar with with_items you can use that too. Each element on the list can be accessed by the variable item
the itemvariable is being used within the debug msgstatement where we are applying the splitacross each email ID
The result of the split would be a list with two items. which can be accessed using Ansible special filters first and last
firstis to get the first element of the list more likelist[0]lastis to get the last element of the list more likelist[-1]orlist[len(list)-1]
In our case, we know prior that there would be only two values in the returned list of split. so we can use the last here to get the domain names as our seperator is @
---
- name: Ansible Split Examples
hosts: localhost
vars:
- emails: ['[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]']
tasks:
- name: print only domain Names from Email IDs with Split
debug: msg="{{ item | split('@') | last }}"
loop: "{{emails}}"
Example3: Ansible Split with Map - To process Nested Lists
Here is the source code of the second playbook
---
- name: Ansible Split Examples
hosts: localhost
vars:
- emails: ['[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]']
tasks:
- name: print only domain names from Email IDs with Split
debug: msg={{ emails | map('split','@') | flatten | select('match','.+\..+$') }}
The reason we are using the map filter here is that we want to apply the split function on the elements of the list. not on the list itself.
If it is a simple string that we want to split we can simply do it like this
msg: "{{ '[email protected]' | split('@') | last }}"
but our email ids are stored inside the list and in our last example, we have iterated over the list emails and passed each email id to for the split processing with item
Now instead of using loop we are using Ansible Map filter
To know more about the Ansible map refer to our dedicated article here.
flatten is used here to convert the list of lists ( nested lists ) into a single list.
Ideally, the result of the map and split would be like this, [[],[],[],[]]a Nested list/array
"msg": [ [ "hello", "gritfy.com" ], [ "steve", "google.com" ], [ "mark", "ibm.com" ], [ "dave", "meta.com" ], [ "admin", "gritfy.in" ] ] }
and with flatten it would become like this, A single list with multiple values.
"msg": [ "hello", "gritfy.com", "steve", "google.com", "mark", "ibm.com", "dave", "meta.com", "admin", "gritfy.in" ]
Now our job is to get the elements matching a regex pattern *.[org|com] etc. That's, where we are using select
select is a jinja2 filter that helps us to select the matching item from the list, with select we are going to apply another filter named match to perform the regular expression pattern matching.
Our regular expression is this .+\..+$ to select the domain from the list. you can try this pattern in regex101.com to find out what it does ( if you are new to regex)
The result of this second playbook would be like this
Much simpler and neat. everything is done in a single line with no loop.
Example4: Ansible Split - With File Content
As part of this example, we are going to read a file named /etc/passwd from the filesystem and process it line by line and split based on separator
---
- name: Ansible Split Examples
hosts: localhost
vars:
- usernames : []
tasks:
- name: print only domain names from Email IDs with Split
set_fact:
usernames: '{{ usernames + [ item | split(":") | first ] }}'
loop: "{{ lookup('file', '/etc/passwd').splitlines() | select('match','^(?!#)')}}"
- debug: var=usernames
we have used a few functions/filters here, let us decode each one of them
to begin with, let us start with loop expression
"{{ lookup('file', '/etc/passwd').splitlines() | select('match','^(?!#)')}}"
Here the
lookupfilter is used to read the content of the filessplitlinesis to split the file content line by lineselectfilter to execute another filter to select a matching element from the sequence. ( it is different from selectattr)matcha filter being executed by select. to perform regular expression matching
Here is the output of this playbook.
Conclusion
In this detailed article about Ansible Split. I tried to cover not just the simple split but also to cover how can you use it with dist, List etc
we have also talked about various other filters and topics like
- How to read a file content into Ansible split into lines
- Selecting elements from the LIST using
select - Regular expression pattern matching using
match - How to use
loopand iteration statements - How to use expressions with
loopetc.
Hope you would find this article helpful.
Cheers
Sarav AK
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content










