如何有效地循环和合并查找/csv文件的字段?

sd2nnvve  于 2023-01-15  发布在  其他
关注(0)|答案(2)|浏览(96)

我想循环并将查找/csv文件的字段合并到列表中。
以下是CSV文件示例并读入列表(hosts_list

id,hostname,host_ip,country_code,country_name
ID01,myhost1,10.2.3.2,US,United States
ID02,myhost2,10.2.3.3,US,United States
ID03,myhost3,10.2.3.4,UK,United Kingdom
ID04,myhost3,10.2.3.4,US,United Kingdom

预期输出为

['US-myhost1', 'US-myhost2', 'US-myhost3']

我用了两种方法
一个二个一个一个
有没有更好/更有效的方法来做到这一点?

balp4ylt

balp4ylt1#

简而言之:

---
- hosts: localhost
  gather_facts: false

  vars:
    hosts_query: >-
      [][country_code,hostname].join('-', @)
    hosts_list: "{{ hosts_csv.list | d([]) | json_query(hosts_query) }}"

  tasks:
    - name: Get CSV content
      ansible.builtin.read_csv:
        path: files/hosts.csv
      register: hosts_csv

    - name: Show calculated hosts list
      ansible.builtin.debug:
        var: hosts_list

如果没有jmespath/json_query可用,最终可以将上面的vars部分替换为:

vars:
    hosts_codes: "{{ hosts_csv.list | d([]) | map(attribute='country_code') }}"
    hosts_names: "{{ hosts_csv.list | d([]) | map(attribute='hostname') }}"
    hosts_list: "{{ hosts_codes | zip(hosts_names) | map('join', '-') }}"

在这两种情况下,使用上述CSV内容,我们得到:

TASK [Get CSV content] *****************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show calculated hosts list] ******************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "hosts_list": [
        "US-myhost1",
        "US-myhost2",
        "UK-myhost3",
        "US-myhost3"
    ]
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
gdx19jrr

gdx19jrr2#

使用Jinja模板。例如,

clubbed_str: |
    {% for i in hosts_csv.list|groupby('country_code') %}
    {{ i.0 }}:
    {% for h in i.1|map(attribute='hostname') %}
      - {{ i.0 }}-{{ h }}
    {% endfor %}  
    {% endfor %}
  clubbed_dir: "{{ clubbed_str|from_yaml }}"

给予

clubbed_dir:
    UK: [UK-myhost3]
    US: [US-myhost1, US-myhost2, US-myhost3]

完整的测试行动手册示例

- hosts: localhost

  vars:

    clubbed_str: |
      {% for i in hosts_csv.list|groupby('country_code') %}
      {{ i.0 }}:
      {% for h in i.1|map(attribute='hostname') %}
        - {{ i.0 }}-{{ h }}
      {% endfor %}  
      {% endfor %}
    clubbed_dir: "{{ clubbed_str|from_yaml }}"

  tasks:

    - name: Get CSV content
      ansible.builtin.read_csv:
        path: "{{ playbook_dir }}/files/hosts.csv"
      register: hosts_csv

    - debug:
        var: clubbed_dir|to_yaml
    - debug:
        var: clubbed_dir.US|to_yaml

给予

PLAY [localhost] *****************************************************************************

TASK [Get CSV content] ***********************************************************************
ok: [localhost]

TASK [debug] *********************************************************************************
ok: [localhost] => 
  clubbed_dir|to_yaml: |-
    UK: [UK-myhost3]
    US: [US-myhost1, US-myhost2, US-myhost3]

TASK [debug] *********************************************************************************
ok: [localhost] => 
  clubbed_dir.US|to_yaml: |-
    [US-myhost1, US-myhost2, US-myhost3]

PLAY RECAP ***********************************************************************************
localhost: ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

相关问题