neteng225
neteng225

Reputation: 71

Performing regex_findall and split() on the same line

Here is the output that I'm trying to parse:

hostname#show bgp vrf vrfname summary | i 1.1
BGP Route Distinguisher: 1.1.1.1:0
BGP router identifier 1.1.1.1, local AS number 2222
1.1.1.3      0 64512  349608  316062   896772    0    0     2w4d          1

I have the following regex that succesfully matches just the last line. Now I need to split that line and view the last index. In this case it is "1", but I will want to fail if that value is "0".

- name: debug test
  debug:
    msg: "{{show_bgp_sessions.data | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*')}}"

I tried adding a split in a couple different formats at the end of the "msg" line so that I can grab the last index to compare it in the failed_when statement:

msg: "{{show_bgp_sessions.data | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*') | split(' ')}}"

But I'm getting the following error msg:

 "template error while templating string: no filter named 'split'. String:

I've also tried to use a few different forms of "ends_with" to verify the last index in the string as I've used that a lot in my python experience, but I can't get it to work in ansible. I can't create a new task to parse the data and perform the split seperately because I need to run this verification through a loop.

Upvotes: 3

Views: 4161

Answers (2)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39264

Possibly the regex provided by @Thefourthbird is a better solution.

But for your issue at hand, this is caused by the fact that there is indeed no filter split in Jinja, see the list there: https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-builtin-filters.

The reason why there is no such a filter is simple: split() is a function of the Python String, and since Jinja is Python, you can just use it as is.

Also mind that, since regex_findall is meant for multiple matches, you'll have to select the first element of the list, for example, with the filter first.

So your message ends up being:

msg: >-
  {{ 
    (
      show_bgp_sessions.data 
      | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*') 
      | first
    ).split() 
  }}

Given the playbook:

- hosts: all
  gather_facts: no
  vars:
    show_bgp_sessions:
      data: |
        hostname#show bgp vrf vrfname summary | i 1.1
        BGP Route Distinguisher: 1.1.1.1:0
        BGP router identifier 1.1.1.1, local AS number 2222
        1.1.1.3      0 64512  349608  316062   896772    0    0     2w4d          1
        
  tasks:
    - debug:
        msg: >-
          {{ 
            (
              show_bgp_sessions.data 
              | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*') 
              | first
            ).split() 
          }}

Gives the recap:

TASK [debug] ***************************************************************
ok: [localhost] => {
    "msg": [
        "1.1.1.3",
        "0",
        "64512",
        "349608",
        "316062",
        "896772",
        "0",
        "0",
        "2w4d",
        "1"
    ]
}

Upvotes: 1

Vladimir Botka
Vladimir Botka

Reputation: 68134

When you select the line, reverse the string, and split the first item. For example

msg: "{{ (my_line|reverse).split()|first }}"

Upvotes: 4

Related Questions