如何将Ansible变量内容插入CSV文件?解决双变量同列问题
解决Ansible写入CSV时多变量列错位问题
你的问题出在user_data.stdout是多行文本(每个用户占一行),直接和host_data.stdout拼接后,换行符会破坏CSV结构——所有用户会挤在第一列的同一单元格里,还可能让主机名跑到单独的行,导致列错位。另外,获取主机名的命令没必要用awk,/etc/hostname本身就是单行内容,直接读取即可。
方法一:遍历用户列表逐行写入CSV
适合用户数量不多的场景,用loop遍历user_data.stdout_lines(Ansible自动拆分的每行内容列表),每行生成用户名,主机名的格式:
- name: "fetch remote host data" hosts: "redhat" tasks: - name: 获取用户列表 shell: awk -F: '{print $1}' /etc/passwd register: user_data - name: 获取主机名 command: cat /etc/hostname register: host_data - name: 创建CSV表头 local_action: module: copy dest: /tmp/output.csv content: "users,host_data\n" force: no # 仅当文件不存在时创建表头 - name: 写入用户与主机名对应行 local_action: module: lineinfile dest: /tmp/output.csv line: "{{ item }},{{ host_data.stdout }}" loop: "{{ user_data.stdout_lines }}"
方法二:用Jinja2模板批量生成CSV(更高效)
适合用户数量多的场景,通过模板一次性生成所有内容,避免多次调用lineinfile:
- 先创建本地模板文件(比如
templates/user_host.csv.j2):
users,host_data {% for user in user_data.stdout_lines %} {{ user }},{{ host_data.stdout }} {% endfor %}
- 修改playbook:
- name: "fetch remote host data" hosts: "redhat" tasks: - name: 获取用户列表 shell: awk -F: '{print $1}' /etc/passwd register: user_data - name: 获取主机名 command: cat /etc/hostname register: host_data - name: 生成CSV文件 local_action: module: template src: templates/user_host.csv.j2 dest: /tmp/output.csv
关键修改说明
- 用
user_data.stdout_lines代替user_data.stdout:Ansible会自动把命令输出的每行拆成列表,方便遍历处理 - 获取主机名改用
command: cat /etc/hostname:比awk更简洁,避免不必要的字段拆分操作 - 表头创建用
copy模块加force: no:防止每次运行playbook都覆盖已有的表头 - 批量生成用模板:减少Ansible对本地文件的IO操作,执行效率更高
内容的提问来源于stack exchange,提问作者Evarist
相关产品推荐
相关产品推荐

