如何转换“key = value;”的字符串与 ansible 中的字典配对?

问题描述 投票:0回答:2

本质上我正在寻找这个,但是对于 ansible/jinja2: 将逗号分隔的键值对字符串转换为字典

我从 mariadb galera 服务器 wsrep_provider_options 获取一个以分号分隔的键=值对列表:

mariadb_wsrep_provider_options_output = 'base_dir = /var/lib/mysql/; base_host = 192.168.1.101; base_port = 4567;'

用 ansible

register
存储该输出后,我尝试将其解析为字典,如下所示:

mariadb_wsrep_provider_options_output:
  base_dir: /var/lib/mysql/
  base_host: 192.168.1.101
  base_port: 4567
  ...

我尝试过类似的方法,但我不知道如何将其转换回

dict

- debug:
    msg: "{% for item in mariadb_wsrep_provider_options_output.split(';') %} {{ item.split('=') }} {% endfor %}"

编辑:我让它可以完成以下任务,但看起来很笨重:

- set_fact:
    new_var: "{{ new_var|d([]) + [{ 'key': item.split('=')[0]|trim, 'value': item.split('=')[1]|trim }] }}"
    loop: "{{ mariadb_wsrep_provider_options_output.split(';') }}"
- debug:
    var: new_var | items2dict

输出:

    "new_var|items2dict": {
        "base_dir": "/var/lib/mysql/",
        "base_host": "192.168.100.153",
        "base_port": "4567"
    }
python ansible mariadb jinja2 galera
2个回答
2
投票

试试这个

    - set_fact:
        new_var: "{{ dict(_keys|zip(_vals)) }}"
      vars:
        _arr: "{{ mdb_out.split(';')|map('trim')|select()|list }}"
        _keys: "{{ _arr|map('regex_replace', '^(.*?)=(.*)$', '\\1')|map('trim')|list }}"
        _vals: "{{ _arr|map('regex_replace', '^(.*?)=(.*)$', '\\2')|map('trim')|list }}"

给予

  new_var:
    base_dir: /var/lib/mysql/
    base_host: 192.168.1.101
    base_port: '4567'

您的代码经过一些更改也可以正常工作

    - set_fact:
        new_var: "{{ new_var|d({})|combine({_key: _val}) }}"
      loop: "{{ mdb_out.split(';') }}"
      when: item|length > 0
      vars:
        _key: "{{ item.split('=')[0]|trim }}"
        _val: "{{ item.split('=')[1]|trim }}"

从 Ansible 2.11 开始,

split可以用作过滤器。您可以在此处使用它代替 regex_replace。下面的任务给出了相同的结果

    - set_fact:
        new_var: "{{ dict(_keys|zip(_vals)) }}"
      vars:
        _arr: "{{ mdb_out.split(';')|map('trim')|select()|list }}"
        _keys: "{{ _arr|map('split', '=')|map('first')|map('trim')|list }}"
        _vals: "{{ _arr|map('split', '=')|map('last')|map('trim')|list }}"

0
投票

使用

community.general.dict
过滤器可以更轻松地完成此操作。

- name: create test case
  set_fact:
    mdb_out: 'base_dir = /var/lib/mysql/; base_host = 192.168.1.101; base_port = 4567;'
- name: create and print dict
  ansible.builtin.debug:
    msg: "{{ mdb_out | trim(';') | split('; ') | map('split', ' = ', 1) | community.general.dict }}"

步骤如下:

  1. 如果需要,修剪分号。这可以防止拆分时出现空项目。
  2. ; 
    上拆分会创建
    ['key = value','key2 = value2']
    的列表。
  3. 现在,对于列表中的每个元素,在第一次出现
    =
    时进行拆分。
  4. 使用字典过滤器将键/值元组列表转换为字典。
© www.soinside.com 2019 - 2024. All rights reserved.