Score:1

How to parse a map?

hu flag

I'm trying to create a list in ansible which consists of some docker container information. First, I'm running a command module which returns this in stdout:

"map[key1:value1 key2:value2 key3:value3]"

How can I parse this further to get the values based on the key that I provide? When I use a map filter, I get this:

"msg": "<generator object do_map at 0x7f3845b8a740>"

If I run the list filter, I just get output as every single character in the map, so ["m", "a", "p", "[", "k", ...]

What filter should I use?

anx avatar
fr flag
anx
You can get around parsing if the command you get this from can output some common serialization format (Does it have a `--json` option?)
Michael Hampton avatar
cz flag
That looks like output from some Go program. Check with its developers to see if you can get it in some more easily parseable format, such as JSON. I would guess that maybe it's output from some `docker` command, but you didn't specify (and you should have). If that is the case, then use its `--format` option to get exactly what you need in JSON format.
Score:1
br flag

For example

    - set_fact:
        x: "{{ _dict|from_yaml }}"
      vars:
        _regex: '^(.*)\[(.*)\](.*)$'
        _key: "{{ stdout|regex_replace(_regex, '\\1') }}"
        _val: "{{ stdout|regex_replace(_regex, '\\2') }}"
        _dict: |
          {{ _key }}:
          {% for i in _val.split() %}
            {{ i|regex_replace(':', ': ') }}
          {% endfor %}

gives

  x:
    map:
      key1: value1
      key2: value2
      key3: value3

If there were more lines, e.g.

    stdout_lines:
      - "map1[key1:value1 key2:value2 key3:value3]"
      - "map2[key1:value1 key2:value2 key3:value3]"
      - "map3[key1:value1 key2:value2 key3:value3]"

it would be possible to combine the dictionary, e.g.

    - set_fact:
        x: "{{ x|d({})|combine(_dict|from_yaml) }}"
      loop: "{{ stdout_lines }}"
      vars:
        _regex: '^(.*)\[(.*)\](.*)$'
        _key: "{{ item|regex_replace(_regex, '\\1') }}"
        _val: "{{ item|regex_replace(_regex, '\\2') }}"
        _dict: |
          {{ _key }}:
          {% for i in _val.split() %}
            {{ i|regex_replace(':', ': ') }}
          {% endfor %}

gives

  x:
    map1:
      key1: value1
      key2: value2
      key3: value3
    map2:
      key1: value1
      key2: value2
      key3: value3
    map3:
      key1: value1
      key2: value2
      key3: value3

If the keys were repeating, e.g.

    stdout_lines:
      - "map[key1:value1 key2:value2 key3:value3]"
      - "map[key1:value1 key2:value2 key3:value3]"
      - "map[key1:value1 key2:value2 key3:value3]"

it would be possible to concatenate a list, e.g.

    - set_fact:
        x: "{{ x|d([]) + [_dict|from_yaml] }}"
      loop: "{{ stdout_lines }}"
      vars:
        _regex: '^(.*)\[(.*)\](.*)$'
        _key: "{{ item|regex_replace(_regex, '\\1') }}"
        _val: "{{ item|regex_replace(_regex, '\\2') }}"
        _dict: |
          {{ _key }}:
          {% for i in _val.split() %}
            {{ i|regex_replace(':', ': ') }}
          {% endfor %}

gives

  x:
  - map:
      key1: value1
      key2: value2
      key3: value3
  - map:
      key1: value1
      key2: value2
      key3: value3
  - map:
      key1: value1
      key2: value2
      key3: value3
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.