在 Ansible 剧本中使用 panda 或 bash 将两个具有不同列的 CSV 文件连接成一个文件

Concatenate two CSV files with different columns into one using panda or bash within an Ansible playbook

这是我的第一个 post,我对编程也很陌生。对不起,如果我使用的术语并不总是很有意义。请随时纠正任何会让您眼睛流血的non-sense。

我实际上是一名网络工程师,但根据我所在领域的当前趋势,我需要开始编码和自动化,但 post 在我的公司有一个真正的用例之前一直在努力。好吧,那个用例到了,它被称为 ACI。

我一直在学习如何使用 ansible 自动化许多基本的事情,到目前为止一切顺利。

我当前的用例需要一个剧本,它将两个具有不同列的 CSV 文件连接成一个 CSV 文件,稍后将用于在其他剧本中设置变量。

我们主要处理包含系统名称、VLAN ID 和叶端口的 CSV 文件,如下所示:

VPC_SYS_NAME, VLAN_ID, LEAF_PAIR
sys1,          3001,     101-102
sys2,          2500,     111-112
... ,          ...,      ... ...

到目前为止,我尝试的是获取这些数据,使用 ansible 中的 read_csv 模块读取它,并将每列中的字段用作变量以在另一个播放中循环:

- name: read the csv file
  read_csv:
       path: list.csv
       delimiter: ','
  register: csv

- name: GET EPG UNI PATH FROM VLAN ID
      aci_rest:
        host: "{{ ansible_host }}"
        username: "{{ username }}"
        password: "{{ password }}"
        validate_certs: False
        method: get
        path:  api/class/fvAEPg.json?query-target-filter=eq(fvAEPg.name,"{{item.VLAN_ID}}")
      loop: "{{ csv.list }}"  
      register: register_as_variable

一旦这个播放结束,它会将输出注册到另一个变量中,在本例中,称为 register_as_variable

然后我用 json_query 解析此输出并将其设置为一个新变量:

- set_fact:
     fact1: "{{ register_as_variable | json_query('results[].imdata[].fvAEPg.attributes.dn') }}" 

最后,我将此输出复制到另一个 CSV 文件中。

使用 Ansible shell 模块并使用 catawk 我删除了所有不需要的字符并将 CSV 文件从单行列表更改为 headerless专栏,得到这样的东西:

"uni/tn-tenant/ap-AP01/epg-3001",
"uni/tn-tenant/ap-AP01/epg-2500",
"uni/tn-tenant/ap-AP01/epg-...",

到目前为止,它按我预期的那样工作(即使它显然不是最干净的方式)。

我目前正在努力的地方是找到一种方法来 merge/concatenate 带有系统名称、VLAN ID 等的原始 CSV 和带有输出“uni/tn-tenant/ap-AP01/epg- 的新创建的 CSV ....”到一个独特的“主”CSV 文件中,供其他戏剧使用。 “主”CSV 文件应如下所示:

VPC_SYS_NAME, VLAN_ID, LEAF_PAIR, MO_PATH
sys1,          3001,     101-102, "uni/tn-tenant/ap-AP01/epg-3001",
sys2,          2500,     111-112, "uni/tn-tenant/ap-AP01/epg-2500",
... ,          ...,      ... ..., "uni/tn-tenant/ap-AP01/epg-....",

添加 MO_PATH header 可以用 sed -i '1iMO_PATH' file.csv 完成,但是我无法按给定顺序合并两个文件的列。

到目前为止,我已经尝试使用 panda 和 cat 但没有成功。

如果有人能帮我一点忙或指导我正确的方向,我将不胜感激。

谢谢!

您好,欢迎来到 Whosebug!一位前网络工程师在这里提供帮助:)

逐行合并两个文件的最简单方法(如果您确定它们的顺序是正确的)是使用 paste 实用程序。

我有以下文件:

1.csv

VPC_SYS_NAME,VLAN_ID,LEAF_PAIR
sys1,3001,101-102
sys2,2500,111-112

2.csv

"uni/tn-tenant/ap-AP01/epg-3001",
"uni/tn-tenant/ap-AP01/epg-2500",

然后我想到了

  1. 正在将新的 header 添加到生成的文件 3.csv:

    echo "$(head -n 1 1.csv),MO_PATH" > 3.csv
    

    我们正在读取 1.csv 的 header,添加缺失的列并将输出重定向到 3.csv(同时完全覆盖它)

  2. 使用粘贴实用程序合并两个文件,同时跳过 1.csv

    的 header
    tail -n+2 1.csv | paste -d"," - 2.csv >> 3.csv
    

    让我们分开这个:

    • tail -n+2 1.csv - 从第 2 行开始读取 1 个 csv 到 stdout

    • paste -d"," - 2.csv - 逐行合并两个文件,使用 , 作为分隔符,同时从标准输入获取第一个文件的内容(表示为 -) .我们使用管道 | 符号将 tail 命令的 stdout 传递给 paste 命令的 stdin

    • >> 用于将内容追加到已经存在的 3.csv

  3. 结果:

VPC_SYS_NAME,VLAN_ID,LEAF_PAIR,MO_PATH
sys1,3001,101-102,"uni/tn-tenant/ap-AP01/epg-3001",
sys2,2500,111-112,"uni/tn-tenant/ap-AP01/epg-2500",

为了管道工作,不要忘记使用 shell 模块而不是命令,因为这个问题被标记为 ansible