Ansible:如何将“read_csv”读取为动态变量名称?

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

我正在尝试从 CSV 文件 (fileglob) 列表中读取,并且这些文件具有标准命名约定。只是想使用

read_csv
register
/
set_fact
读取 CSV 文件到文件名,这应该是变量名。

文件是

apples.csv
pears.csv
grapes.csv

我尝试过的,(接近但不正确)

- name: "Read into dynamic variables"
  read_csv:
    path: "{{ item }}"
  with_fileglob:
    - "/tmp/fruits/*.csv"
  fruit_name: "{{ item | basename | regex_replace('.csv') }}"
  register: "fruit_{{ fruit_name }}"

因此理想情况下希望将每个 CSV 的内容作为变量的一部分,例如

fruit_apples
稍后可以在其他戏剧中重复使用。

csv ansible
2个回答
3
投票

例如,给定文件

shell> tree fruits/
fruits/
├── apples.csv
├── grapes.csv
└── pears.csv

0 directories, 3 files
shell> cat fruits/apples.csv 
red,big,20
green,small,10
shell> cat fruits/grapes.csv 
red,big,20
black,small,10
shell> cat fruits/pears.csv 
green,big,30
yellow,small,20

阅读文件

    - read_csv:
        fieldnames: color,size,price
        path: "{{ item }}"
      with_fileglob: fruits/*.csv
      register: fruit

创建水果字典更简单,而不是创建变量 fruit_*。例如,将下面的声明设置为 property

fruits: "{{ dict(f_keys | zip(f_vals)) }}"
f_vals: "{{ fruit.results | map(attribute='list') | list }}"
f_keys: "{{ fruit.results | map(attribute='item')
                          | map('basename')
                          | map('splitext')
                          | map('first') | list }}"

给予

fruits:
  apples:
    - {color: red, price: '20', size: big}
    - {color: green, price: '10', size: small}
  grapes:
    - {color: red, price: '20', size: big}
    - {color: black, price: '10', size: small}
  pears:
    - {color: green, price: '30', size: big}
    - {color: yellow, price: '20', size: small}

完整剧本示例

- hosts: localhost

  vars:

    fruits: "{{ dict(f_keys | zip(f_vals)) }}"
    f_vals: "{{ fruit.results | map(attribute='list') | list }}"
    f_keys: "{{ fruit.results | map(attribute='item')
                              | map('basename')
                              | map('splitext')
                              | map('first') | list }}"

  tasks:

    - read_csv:
        fieldnames: color,size,price
        path: "{{ item }}"
      with_fileglob: fruits/*.csv
      register: fruit

    - debug:
        var: fruits

    - debug:
        var: fruits.apples

1
投票

这是不可能的。根据注册变量

”当您在带有循环的任务中注册变量时,注册的变量包含循环中每个项目的值。循环期间放置在变量中的数据结构将包含一个

results
属性,即列表来自模块的所有响应。”

因此您需要在接下来的任务中提取您感兴趣的部分。

为了更好地理解我创建了一个小测试的行为

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: Create multiple results and register them
    debug:
      msg: "{{ item }}"
    loop: [A, B, C]
    register: result

  - name: Show result
    debug:
      msg: "{{ result }}"

显示了等效的行为,因为

with_fileglob
是一个
with_X
样式循环。

TASK [Create multiple results and register them] ***
ok: [localhost] => (item=A) =>
  msg: A
ok: [localhost] => (item=B) =>
  msg: B
ok: [localhost] => (item=C) =>
  msg: C

TASK [Show result] *********************************
ok: [localhost] =>
  msg:
    changed: false
    msg: All items completed
    results:
    - ansible_loop_var: item
      changed: false
      failed: false
      item: A
      msg: A
    - ansible_loop_var: item
      changed: false
      failed: false
      item: B
      msg: B
    - ansible_loop_var: item
      changed: false
      failed: false
      item: C
      msg: C

进一步问答

© www.soinside.com 2019 - 2024. All rights reserved.