filteransible

Filter based on index - Ansible


I would like to know how to extract a string which comes next to 4th occurrence of \\\\\\\\ (4 backslashes), through an Ansible filter.

Input derived from Registering variable

{"ansible_facts": {"dn_var": ["\\\\TEST1\\\\TEST2\\\\TEST 3\\\\TEST 4\\\\TEST 5\\\\TEST 6\\\\TEST 7\\\\TEST 8"]}, "changed": false}

Output expected is Test 4

I've tried to filter using below

- name: to filter
  set_fact:
    team_name: "{{ dn_var.split('\\\\')[3] }}"

but getting this error

The error was: 'list object' has no attribute 'split'

Suggestions would be helpful. Thanks.


Solution

  • Since it is not clear from your question what exactly you are doing and how the input looks like, sometimes it is \\, sometimes it is \\\\, sometime dn_vars is a list with one element and because you haven't provided a Minimal, Reproducible Example, an other approach with Input Data Normalization might work. It is based on the already given answer which should be the accepted answer.

    A minimal example playbook

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      vars:
    
        dn_vars:
          - "\\TEST1\\TEST2\\TEST 3\\TEST 4\\TEST 5\\TEST 6\\TEST 7\\TEST 8"
          - '\\TEST1\\TEST2\\TEST 3\\TEST 4\\TEST 5\\TEST 6\\TEST 7\\TEST 8'
          - \\\\TEST1\\\\TEST2\\\\TEST 3\\\\TEST 4\\\\TEST 5\\\\TEST 6\\\\TEST 7\\\\TEST 8
    
        delimiter: '\'
        index: 3
    
      tasks:
    
        - debug:
            var: dn_vars
    
        - name: Data normalization
          debug:
            msg: '{{ item | regex_replace("([\\]+)", "\\") }}'
          loop: "{{ dn_vars }}"
          loop_control:
            extended: true
            label: "{{ ansible_loop.index0 }}"
    
        - name: Split with Python method
          debug:
            msg: '{{ ((dn_vars | first | regex_replace("([\\]+)", "\\")).split(delimiter) | select)[index] }}'
    
        - name: Split as of Ansible Core v2.11
          debug:
            msg: '{{ (dn_vars | first | regex_replace("([\\]+)", "\\") | split(delimiter) | select)[index] }}'
    

    will result into an output of

    TASK [debug] *********************************************************************
    ok: [localhost] =>
      dn_vars:
      - \TEST1\TEST2\TEST 3\TEST 4\TEST 5\TEST 6\TEST 7\TEST 8
      - \\TEST1\\TEST2\\TEST 3\\TEST 4\\TEST 5\\TEST 6\\TEST 7\\TEST 8
      - \\\\TEST1\\\\TEST2\\\\TEST 3\\\\TEST 4\\\\TEST 5\\\\TEST 6\\\\TEST 7\\\\TEST 8
    
    TASK [Data normalization] ***********************************
    ok: [localhost] => (item=0) =>
      msg: \TEST1\TEST2\TEST 3\TEST 4\TEST 5\TEST 6\TEST 7\TEST 8
    ok: [localhost] => (item=1) =>
      msg: \TEST1\TEST2\TEST 3\TEST 4\TEST 5\TEST 6\TEST 7\TEST 8
    ok: [localhost] => (item=2) =>
      msg: \TEST1\TEST2\TEST 3\TEST 4\TEST 5\TEST 6\TEST 7\TEST 8
    
    TASK [Split with Python method] *****************************
    ok: [localhost] =>
      msg: TEST 4
    
    TASK [Split as of Ansible Core v2.11] ***********************
    ok: [localhost] =>
      msg: TEST 4
    

    It will work any input list element, like dn_vars | last ... or (dn_vars)[1].