如何在Ansible中针对CSV每行循环处理冒号分隔的prefix值
问题场景
我有一个sample.csv文件,内容如下:
table_name,column_name,prefix segment_100,test1:null:string,x:y/1:z/1 segment_100,test2_name:null:string,p:q/1 segment_101,test3_name:null:string,foo
使用Ansible 2.9.9编写Playbook时,读取该CSV后用with_nested循环出现问题:所有CSV行都复用了第一行prefix字段的分割结果,而不是每行处理自身的prefix分割值。需要实现针对每行,循环处理自身冒号分隔的每个prefix值(用debug模块模拟执行shell命令),要求每行仅使用自身的分割后prefix值。
问题原因
之前用with_nested的错误在于:提前全局分割所有行的prefix并生成一个统一列表,再和CSV行列表做嵌套循环,导致所有行都和第一行的分割结果配对,而非每行对应自己的分割值。正确的逻辑应该是在每行的循环上下文内分割当前行的prefix。
解决方案
方法1:直接嵌套双层循环(推荐,更简洁)
不需要额外预处理,直接在外层遍历CSV行,内层遍历当前行分割后的prefix列表:
--- - name: 处理CSV每行的prefix分割值 hosts: localhost gather_facts: false tasks: - name: 读取CSV文件 read_csv: path: sample.csv register: csv_content - name: 遍历每行并处理自身的prefix项 debug: msg: "处理表 {{ csv_row.table_name }},字段 {{ csv_row.column_name }},prefix值 {{ single_prefix }}" # 内层循环:分割当前行的prefix loop: "{{ csv_row.prefix.split(':') }}" loop_control: loop_var: single_prefix # 外层循环:遍历所有CSV行 with_items: "{{ csv_content.list }}" loop_control: loop_var: csv_row
方法2:预处理生成带分割列表的行数据
先给每行添加一个分割后的prefix_list字段,再用with_subelements遍历行和对应的prefix子元素:
--- - name: 处理CSV每行的prefix分割值 hosts: localhost gather_facts: false tasks: - name: 读取CSV文件 read_csv: path: sample.csv register: csv_content - name: 为每行添加分割后的prefix列表 set_fact: csv_rows_with_prefix: "{{ csv_rows_with_prefix | default([]) + [item | combine({'prefix_list': item.prefix.split(':')})] }}" loop: "{{ csv_content.list }}" - name: 遍历每行的每个prefix值 debug: msg: "处理表 {{ item.0.table_name }},字段 {{ item.0.column_name }},prefix值 {{ item.1 }}" with_subelements: - "{{ csv_rows_with_prefix }}" - prefix_list
效果验证
执行后会得到如下符合预期的输出:
ok: [localhost] => (item=x) => { "msg": "处理表 segment_100,字段 test1:null:string,prefix值 x" } ok: [localhost] => (item=y/1) => { "msg": "处理表 segment_100,字段 test1:null:string,prefix值 y/1" } ok: [localhost] => (item=z/1) => { "msg": "处理表 segment_100,字段 test1:null:string,prefix值 z/1" } ok: [localhost] => (item=p) => { "msg": "处理表 segment_100,字段 test2_name:null:string,prefix值 p" } ok: [localhost] => (item=q/1) => { "msg": "处理表 segment_100,字段 test2_name:null:string,prefix值 q/1" } ok: [localhost] => (item=foo) => { "msg": "处理表 segment_101,字段 test3_name:null:string,prefix值 foo" }
内容的提问来源于stack exchange,提问作者Jninja
相关产品推荐
相关产品推荐

