Search code examples
regexparsingansiblejinja2regexp-replace

How to remove unwanted string from dictionary key value from ansible debug


I have below output when i ran a ansible playbook

ok: [localhost] => {
    "msg": [
        {
            "last-heard-processing-time": "18611 secs ago(took 15 secs)",
            "name": "XXXX",
            "status": "conn:Getting ALL"
        },
        {
            "last-heard-processing-time": "20375 secs ago(took 17 secs)",
            "name": "AAAA",
            "status": "conn:Getting ALL"
        },
        {
            "last-heard-processing-time": "20292 secs ago(took 11 secs)",
            "name": "BBBB",
            "status": "conn:Getting ALL"
        },
        {
            "last-heard-processing-time": "4 secs ago(took 13 secs)",
            "name": "CCCC",
            "status": "conn:idle"
        },
        {
            "last-heard-processing-time": "51 secs ago(took 10 secs)",
            "name": "DDDD",
            "status": "conn:idle"
        },
        {
            "last-heard-processing-time": "53 secs ago(took 10 secs)",
            "name": "EEEEE",
            "status": "conn:idle"
        },
        {
            "last-heard-processing-time": "9 secs ago(took 10 secs)",
            "name": "FFFF",
            "status": "conn:idle"
        }
    ]
}

need some help/hint/clue( i am newbie to ansible) from experts on which filter do i need use to remove extra string in 'last-heard-processing-time' key value so that i can get below output, i just need first number in last-heard-processing-time key value

ok: [localhost] => {
    "msg": [
        {
            "last-heard-processing-time": "18611",
            "name": "XXXX",
            "status": "conn:Getting ALL"
        },
        {
            "last-heard-processing-time": "20375",
            "name": "AAAA",
            "status": "conn:Getting ALL"
        },
        {
            "last-heard-processing-time": "20292",
            "name": "BBBB",
            "status": "conn:Getting ALL"
        },
        {
            "last-heard-processing-time": "4",
            "name": "CCCC",
            "status": "conn:idle"
        },
        {
            "last-heard-processing-time": "51",
            "name": "DDDD",
            "status": "conn:idle"
        },
        {
            "last-heard-processing-time": "53",
            "name": "EEEEE",
            "status": "conn:idle"
        },
        {
            "last-heard-processing-time": "9",
            "name": "FFFF",
            "status": "conn:idle"
        }
    ]
}

i'm trying to use regex_replace

msg: "{{output.msg| regex_replace('\\d+\\ssecs\\sago\\(took\\s\\d+\\ssecs\\)', '\\d+')}}"

getting error

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: re.error: bad escape \d at position 0
fatal: [localhost]: FAILED! => {}

Solution

  • Create the list of the first numbers, .e.g

        - set_fact:
            time: "{{ output.msg|
                      map(attribute='last-heard-processing-time')|
                      map('regex_replace', '^(\\d+)\\s+.*$', '\\1') }}"
    

    gives

      time:
      - '18611'
      - '20375'
      - '20292'
      - '4'
      - '51'
      - '53'
      - '9'
    

    Then combine the updated dictionaries and concatenate the list

        - set_fact:
            out: "{{ out|d([]) +
                     [item.0|combine({'last-heard-processing-time': item.1})] }}"
          with_together:
            - "{{ output.msg }}"
            - "{{ time }}"
    

    gives

      out:
      - last-heard-processing-time: '18611'
        name: XXXX
        status: conn:Getting ALL
      - last-heard-processing-time: '20375'
        name: AAAA
        status: conn:Getting ALL
      - last-heard-processing-time: '20292'
        name: BBBB
        status: conn:Getting ALL
      - last-heard-processing-time: '4'
        name: CCCC
        status: conn:idle
      - last-heard-processing-time: '51'
        name: DDDD
        status: conn:idle
      - last-heard-processing-time: '53'
        name: EEEEE
        status: conn:idle
      - last-heard-processing-time: '9'
        name: FFFF
        status: conn:idle
    

    The value of the updated time attribute is a string. Add the int filter if you want an integer instead.

        - set_fact:
            time: "{{ output.msg|
                      map(attribute='last-heard-processing-time')|
                      map('regex_replace', '^(\\d+)\\s+.*$', '\\1')|
                      map('int') }}"