Parsing 如何从Ansible中以宽度分隔的表中提取值?

Parsing 如何从Ansible中以宽度分隔的表中提取值?,parsing,ansible,jinja2,ansible-2.x,ansible-template,Parsing,Ansible,Jinja2,Ansible 2.x,Ansible Template,我试图从打印到stdout的SQL命令的结果中提取值 first second 29494060 23004496 29774383 22979864 我想把它解析成这样的数据结构 [ { first: 29494060, second: 23004496 }, { first: 29774383, second: 22979864 } ] 这样我就可以访问每个记录的值,比如{{item.first}和{{item.second} 我已经能够通过使用re

我试图从打印到stdout的SQL命令的结果中提取值

  first      second
  29494060   23004496
  29774383   22979864
我想把它解析成这样的数据结构

[
  { first: 29494060, second: 23004496 },
  { first: 29774383, second: 22979864 }
]
这样我就可以访问每个记录的值,比如
{{item.first}
{{item.second}

我已经能够通过使用
regex\u 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}default([])+[{…}]}}}的列表连接

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

创建键。比如说

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

然后将过滤器创建的字典添加到列表sql\u列表中

给予


通过简化的任务给出了相同的结果

- set_fact:
    sql_list: "{{ command_out.stdout_lines[1:]|
                  map('string_split')|
                  map('list_dict_zip_rev', keys)|
                  list }}"

谢谢你的回答,弗拉基米尔!它比我同事的解决方案要优雅得多,它将每个元素分配为任务中的变量。我做了一个修改,在
set\u fact
任务中定义
vars:keys:[…]
。按惯例24小时后我接受。
- 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"
    }
]
- 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
        }