Ansible Split Examples - With String, List and File Content

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

Ansible Split

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

Ansible Split

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

  • first is to get the first element of the list more like list[0]
  • last is to get the last element of the list more like list[-1] or list[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

Ansible Split

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

  • lookup filter is used to read the content of the files
  • splitlines is to split the file content line by line
  • select filter to execute another filter to select a matching element from the sequence. ( it is different from selectattr)
  • match a filter being executed by select. to perform regular expression matching

Here is the output of this playbook.

Ansible Split

 

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 loop and iteration statements
  • How to use expressions with loop etc.

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

Buy Me a Coffee at ko-fi.com

Signup for Exclusive "Subscriber-only" Content

Loading