Chris
Chris

Reputation: 19

Ansible regex starting from position x up to pos y

I have the following problem. I need to extract the File ID from the following output of a playbook:

"result_task_id": {
        "changed": false,
        "dnac_response": {
            "response": {
                "endTime": 1674734268584,
                "id": "12393650-c412-4f09-bcc6-25fe24b8b0a9",
                "instanceTenantId": "6305975890949b5614356b66",
                "isError": false,
                "lastUpdate": 1674734268584,
                "progress": "{\"fileId\":\"1ce07c2a-c3f9-46f3-b216-713d043871d6\"}",
                "rootId": "12393650-c412-4f09-bcc6-25fe24b8b0a9",
                "serviceType": "Command Runner Service",
                "startTime": 1674734268134,
                "username": "admin",
                "version": 1674734268584
            },
            "version": "1.0"
        },
        "failed": false,
        "result": ""
    }
}

Selecting the right field result_task_id.dnac_response.response.progress results in this output:

{\"fileId\":\"1ce07c2a-c3f9-46f3-b216-713d043871d6\"}

I just need the ID 1ce07c2a-c3f9-46f3-b216-713d043871d6. The ID itself can differ from run to run but the position will be the same.

Is there a way to use the select('match'...) in order to filter it out?

I need characters 14 until 49. I was not able to find the right regex.

Thanks for the help

Upvotes: 1

Views: 89

Answers (3)

U880D
U880D

Reputation: 12111

Regarding

... from position x to y ... I need characters 14 until 49.

you may have a look into Python slicing.

The minimal example

---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    STRING: '{\"fileId\":\"1ce07c2a-c3f9-46f3-b216-713d043871d6\"}'

  tasks:

  - name: Show slice
    debug:
      msg: "{{ STRING[14:50] }}"

will result into an output of

TASK [Show slice] *************************
ok: [localhost] =>
  msg: 1ce07c2a-c3f9-46f3-b216-713d043871d6

Please notice that such kind of "magic numbers" are a bad practice in programming, as well that kind of hard coding in data structures. Therefore, maintaining a data structure as shown in the other answer given here should be preferred.


Regarding

Is there a way to use the select('match'...) in order to filter it out? ... I was not able to find the right regex.

it seems your use case would be Searching for UUIDs in text with regex. Therefore

  - name: Show UUID
    debug:
      msg: "{{ STRING | regex_search('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') }}"

will result into the required output.

Upvotes: 0

Vladimir Botka
Vladimir Botka

Reputation: 68124

The output of the playbook is a valid JSON. Given the data in a string

  out_str: |
    {
    "result_task_id": {
        "changed": false,
        "dnac_response": {
            "response": {
                "endTime": 1674734268584,
                "id": "12393650-c412-4f09-bcc6-25fe24b8b0a9",
                "instanceTenantId": "6305975890949b5614356b66",
                "isError": false,
                "lastUpdate": 1674734268584,
                "progress": "{\"fileId\":\"1ce07c2a-c3f9-46f3-b216-713d043871d6\"}",
                "rootId": "12393650-c412-4f09-bcc6-25fe24b8b0a9",
                "serviceType": "Command Runner Service",
                "startTime": 1674734268134,
                "username": "admin",
                "version": 1674734268584
            },
            "version": "1.0"
        },
        "failed": false,
        "result": ""
        }
    }

Convert it to a dictionary

  out: "{{ out_str|from_yaml }}"

gives

  out:
    result_task_id:
      changed: false
      dnac_response:
        response:
          endTime: 1674734268584
          id: 12393650-c412-4f09-bcc6-25fe24b8b0a9
          instanceTenantId: 6305975890949b5614356b66
          isError: false
          lastUpdate: 1674734268584
          progress: '{"fileId":"1ce07c2a-c3f9-46f3-b216-713d043871d6"}'
          rootId: 12393650-c412-4f09-bcc6-25fe24b8b0a9
          serviceType: Command Runner Service
          startTime: 1674734268134
          username: admin
          version: 1674734268584
        version: '1.0'
      failed: false
      result: ''

Get the attribute progress

  progress: "{{ out.result_task_id.dnac_response.response.progress }}"

gives

  progress:
    fileId: 1ce07c2a-c3f9-46f3-b216-713d043871d6

Finally, get the value of fileId

  fileId: "{{ progress.fileId }}"

gives

  fileId: 1ce07c2a-c3f9-46f3-b216-713d043871d6

Example of a complete playbook for testing

- hosts: localhost

  vars:

    out_str: |
      {
      "result_task_id": {
          "changed": false,
          "dnac_response": {
              "response": {
                  "endTime": 1674734268584,
                  "id": "12393650-c412-4f09-bcc6-25fe24b8b0a9",
                  "instanceTenantId": "6305975890949b5614356b66",
                  "isError": false,
                  "lastUpdate": 1674734268584,
                  "progress": "{\"fileId\":\"1ce07c2a-c3f9-46f3-b216-713d043871d6\"}",
                  "rootId": "12393650-c412-4f09-bcc6-25fe24b8b0a9",
                  "serviceType": "Command Runner Service",
                  "startTime": 1674734268134,
                  "username": "admin",
                  "version": 1674734268584
              },
              "version": "1.0"
          },
          "failed": false,
          "result": ""
          }
      }
    out: "{{ out_str|from_yaml }}"

    progress: "{{ out.result_task_id.dnac_response.response.progress }}"
    fileId: "{{ progress.fileId }}"

  tasks:

    - debug:
        var: out
    - debug:
        var: progress
    - debug:
        var: fileId

Upvotes: 1

Chris
Chris

Reputation: 19

That was the solution:

  - name: Set File ID
    ansible.builtin.set_fact:
      file_id_list: "{{ result_task_id.dnac_response.response.progress.splitlines()| map ('from_json') }}"
  - debug: var=file_id_list

  - name: Set File ID
    ansible.builtin.set_fact:
      file_id: "{{ file_id_list[0].fileId }}"
  - debug: var=file_id

Upvotes: -1

Related Questions