在 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 模块并使用 cat
和 awk
我删除了所有不需要的字符并将 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",
然后我想到了
正在将新的 header 添加到生成的文件 3.csv:
echo "$(head -n 1 1.csv),MO_PATH" > 3.csv
我们正在读取 1.csv 的 header,添加缺失的列并将输出重定向到 3.csv(同时完全覆盖它)
使用粘贴实用程序合并两个文件,同时跳过 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
结果:
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
这是我的第一个 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 模块并使用 cat
和 awk
我删除了所有不需要的字符并将 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",
然后我想到了
正在将新的 header 添加到生成的文件 3.csv:
echo "$(head -n 1 1.csv),MO_PATH" > 3.csv
我们正在读取 1.csv 的 header,添加缺失的列并将输出重定向到 3.csv(同时完全覆盖它)
使用粘贴实用程序合并两个文件,同时跳过 1.csv
的 headertail -n+2 1.csv | paste -d"," - 2.csv >> 3.csv
让我们分开这个:
tail -n+2 1.csv
- 从第 2 行开始读取 1 个 csv 到 stdoutpaste -d"," - 2.csv
- 逐行合并两个文件,使用,
作为分隔符,同时从标准输入获取第一个文件的内容(表示为-
) .我们使用管道|
符号将 tail 命令的 stdout 传递给 paste 命令的 stdin>>
用于将内容追加到已经存在的 3.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",
为了管道工作,不要忘记使用 shell 模块而不是命令,因为这个问题被标记为 ansible