【问题标题】:How do I extract values from a width delimited table in Ansible?如何从 Ansible 中的宽度分隔表中提取值?
【发布时间】:2019-12-16 06:35:29
【问题描述】:

我正在尝试从打印到标准输出的 SQL 命令的结果中提取值。

  first      second
  29494060   23004496
  29774383   22979864

我想把它解析成一个看起来像这样的数据结构

[
  { first: 29494060, second: 23004496 },
  { first: 29774383, second: 22979864 }
]

这样我就可以访问每条记录的值,例如 {{ item.first }}{{ item.second }}

我已经能够通过使用regex_replace 过滤器提取的值创建一个对象文字来提取单个记录。

- set_fact:
    items: { first: "{{ item | regex_replace('\\s*?(\\d+)\\s*?(\\d+)', '\\1') }}", second: "{{ item | regex_replace('\\s*?(\\d+)\\s*?(\\d+)', '\\2') }}" }
  loop: '{{ command_out.stdout_lines }}'

这只保留最后一行的结果。我无法为每个结果创建一个列表。由于嵌套的 Jinja 模板,我无法使用像 items: "{{ items | default([]) + [{…}] }}" 这样的列表连接。

如何将打印的数据表提取到对象列表中?

【问题讨论】:

    标签: parsing ansible jinja2 ansible-2.x ansible-template


    【解决方案1】:

    创建。例如

    - set_fact:
        keys: "{{ command_out.stdout_lines[0].split() }}"
    - debug:
        var: keys
    

    给予

    "keys": [
        "first", 
        "second"
    ]
    

    然后将过滤器dict and zip 创建的字典添加到列表sql_list

    - set_fact:
        sql_list: "{{ sql_list|default([]) +
                      [dict(keys|zip(item.split()))] }}"
      loop: "{{ command_out.stdout_lines[1:] }}"
    - debug:
        var: sql_list
    

    给予

    "sql_list": [
        {
            "first": "29494060", 
            "second": "23004496"
        }, 
        {
            "first": "29774383", 
            "second": "22979864"
        }
    ]
    

    custom plugins 简化的任务给出了相同的结果

    - set_fact:
        sql_list: "{{ command_out.stdout_lines[1:]|
                      map('string_split')|
                      map('list_dict_zip_rev', keys)|
                      list }}"
    
    $ cat filter_plugins/string_filters.py
    def string_split(s, *i):
        if len(i) == 0:
            return s.split()
        elif len(i) == 1:
            return s.split(i[0])
        else:
            return s.split(i[0], i[1])
    
    def list_dict_zip_rev(l,k):
        return dict((y,x) for x,y in  zip(l,k))
    
    class FilterModule(object):
        ''' Ansible filters.'''
    
        def filters(self):
            return {
                'list_dict_zip_rev' : list_dict_zip_rev,
                'string_split' : string_split
            }
    

    【讨论】:

    • 感谢您的回答弗拉基米尔!它比我同事将每个元素分配为任务中的变量的解决方案要优雅得多。我通过在set_fact 任务中定义vars: keys: […] 进行了一项修改。我会在惯常的 24 小时后接受。
    猜你喜欢
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    相关资源
    最近更新 更多