从csv文件导入python时如何替换数字
Posted
技术标签:
【中文标题】从csv文件导入python时如何替换数字【英文标题】:How to replace numbers when importing from csv file into python 【发布时间】:2022-01-08 03:54:39 【问题描述】:我目前正在编写一个 Python 脚本,以从 csv 文件中提取数据,以利用 Jinja2 模板生成 cisco ASR 配置。所有这些都运行良好;但是,我需要修改一行,以便生成的输出采用正确的 ASR 配置语法。我有数百个这样的事情要做,并且希望能够正确地生成 ASR 配置,以便简单地复制并粘贴到设备中。有人可以指导我最简单的方法吗?
我的 Python 脚本:
import os
import jinja2
import csv
import re
# csv fileused
csv_file = "BFL1_AR1.csv"
with open(csv_file) as f:
read_csv = csv.DictReader(f)
for list_elements in read_csv:
generated_list = list_elements['TEST']
generated_list = generated_list.split()
list_elements['TEST'] = generated_list
pattern = re.findall('4323:(\d1,9)\:\DD', )
print (pattern)
template_file = 'asr_generate_config.j2'
with open(template_file) as f:
list_template = f.read()
template = jinja2.Template(list_template)
print()
print('-' * 80)
print(template.render(list_elements))
print('-' * 80)
print()
生成的输出:
--------------------------------------------------------------------------------
l2*** bridge group 4323:63210:BD
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD mac withdraw state-down
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD mtu 9216
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD interface be10.149
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD interface be50.149
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD vfi 4323:63210:BD
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD vfi 4323:63210:BD ***-id 1024571
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD vfi 4323:63210:BD autodiscovery bgp
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD vfi 4323:63210:BD autodiscovery bgp rd auto
l2*** bridge group 4323:63210:BD bridge-domain 4323:63210:BD vfi 4323:63210:BD autodiscovery bgp route-target 4323:63210
interface be10.149 l2transport
interface be10.149 l2transport description CA/KXFN/201755/LVLC
interface be10.149 l2transport encapsulation dot1q 149
interface be10.149 l2transport rewrite ingress tag pop 1 symmetric
interface be10.149 l2transport ethernet-services access-group L2-FRAMES ingress
interface be50.149 l2transport
interface be50.149 l2transport description CA/KXFN/201755/LVLC
interface be50.149 l2transport encapsulation dot1q 149
interface be50.149 l2transport rewrite ingress tag pop 1 symmetric
interface be50.149 l2transport ethernet-services access-group L2-FRAMES ingress
--------------------------------------------------------------------------------
我需要改变什么:
具有这种数据格式的每个实例: 4323:63210:BD --> 4323_63210
每个客户的网桥组 ID 将保持不变。我需要将第一个分号更改为下划线并删除最后一个分号和 B & D 字母。我一直在尝试使用正则表达式和 re.findall 来做到这一点,但运气不佳。
CSV 文件:
AR Unit ID AR_VLAN TEST CIRCUIT oline lookup uni lookup oline dummy service reference oline svlan assignment oline_BD_assignment oline_RT_assignment oline_***id_assignment end point node ring id Add BFL1-AR1/ 6K Topology New Router Port New_US_6K_Port Add 6K / 7609 Topology New_DS_6K_Port New 6K Port
4 4 MATCH 66/KDFN/102901/TWCS 66/KDFN/102901/TWCS_O_Line 66/KDFN/102901/TWCS DUMMY_OLINE_SVC173 4 4323:63163:BD 4323:63163 1024524 BKFECAAAI6001 #N/A 00GZPP/GE1L/BKFECAAA/BKFECAAA ae10.4 be10.4 00GZQB/GE1L/BKFECAAA/BKFECAAA be50.4 Po50.4
15 15 MATCH 66/KEFN/102374/TWCS 66/KEFN/102374/TWCS_O_Line 66/KEFN/102374/TWCS DUMMY_OLINE_SVC176 15 4323:63166:BD 4323:63166 1024527 BKFECAUZW2001 N66200 00GZPP/GE1L/BKFECAAA/BKFECAAA ae10.15 be10.15 00GZQB/GE1L/BKFECAAA/BKFECAAA be50.15 Po50.15
39 39 MATCH 66/KEFN/102539/TWCS 66/KEFN/102539/TWCS_O_Line 66/KEFN/102539/TWCS DUMMY_OLINE_SVC177 39 4323:63167:BD 4323:63167 1024528 BKFDCA12NN001 N66204 00GZPP/GE1L/BKFECAAA/BKFECAAA ae10.39 be10.39 00GZQB/GE1L/BKFECAAA/BKFECAAA be50.39 Po50.39
50 50 MATCH 66/KFFN/102600/TWCS 66/KFFN/102600/TWCS_O_Line 66/KFFN/102600/TWCS DUMMY_OLINE_SVC203 50 4323:63193:BD 4323:63193 1024554 SHFTCADIW2001 N66198 00GZPP/GE1L/BKFECAAA/BKFECAAA ae10.50 be10.50 00GZQB/GE1L/BKFECAAA/BKFECAAA be50.50 Po50.50
Jinja2 模板
l2*** bridge group oline_BD_assignment
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment mac withdraw state-down
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment mtu 9216
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment interface New_US_6K_Port
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment interface New_DS_6K_Port
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment vfi oline_BD_assignment
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment vfi oline_BD_assignment ***-id oline_***id_assignment
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment vfi oline_BD_assignment autodiscovery bgp
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment vfi oline_BD_assignment autodiscovery bgp rd auto
l2*** bridge group oline_BD_assignment bridge-domain oline_BD_assignment vfi oline_BD_assignment autodiscovery bgp route-target oline_RT_assignment
interface New_US_6K_Port l2transport
interface New_US_6K_Port l2transport description CIRCUIT
interface New_US_6K_Port l2transport encapsulation dot1q AR_VLAN
interface New_US_6K_Port l2transport rewrite ingress tag pop 1 symmetric
interface New_US_6K_Port l2transport ethernet-services access-group L2-FRAMES ingress
interface New_DS_6K_Port l2transport
interface New_DS_6K_Port l2transport description CIRCUIT
interface New_DS_6K_Port l2transport encapsulation dot1q AR_VLAN
interface New_DS_6K_Port l2transport rewrite ingress tag pop 1 symmetric
interface New_DS_6K_Port l2transport ethernet-services access-group L2-FRAMES ingress
【问题讨论】:
【参考方案1】:如果您的 ID 总是采用这种通用形式:
pattern = r'(?P<name>[0-9]4:[0-9]5)'
re.findall(pattern, test_value)
# Will return a list of matches, which you can then substitute the : for a _
或者,如果您想更具体地确保您也匹配 :BD
后缀:
pattern = r'(?P<name>[0-9]4:[0-9]5):[A-Z]2'
在获得更多细节后添加一些编辑:
def convert(old_id):
pattern = r'(?P<name>[0-9]4:[0-9]5)'
matches = re.match(pattern, old_id)
if matches:
match=matches[0]
else:
return 'some_default'
return match.replace(':','_')
或者没有正则表达式:
def convert_simple(old_id):
return '_'.join(old_id.split(':')[:2])
但是,这不会对 ID 的形式进行验证,所以如果您确信 csv 中的 ID 都是正确的,那么就去做吧。
您可以使用该方法将ID的:
格式的格式转换为_
格式的格式
然后在你的代码中我会得到旧的 ID
old_id = list_elements['oline_BD_assignment']
new_id = convert(old_id)
list_elements['oline_BD_assignment'] = new_id
【讨论】:
感谢您的快速回复。我正在尝试您的第一个解决方案,但出现以下错误: Traceback (last most recent call last): File "c:\Users\AC95991\Python3 projects\ASR config generator.py", line 15, intest_value
但您想用存储要从中提取桥域的每一行的变量替换它
意志。我对编程很陌生。我没有完全理解。所需的变量是否在 for 循环中定义?变量将等于什么?请帮我理解。
没关系 - 我不确定在不知道 csv 文件的内容和模板的情况下是否能够真正帮助您,以了解您如何操作 csv 文件的每一行。但基本上听起来您可能需要另一个循环来遍历list_elements
的每个元素并在每一行上运行匹配以提取桥 ID,然后将其替换为所需格式的 ID。也就是说,如果我从您提供的输出中正确猜到了您的模板在做什么。
即csv文件的列标题和一行。 CSV 文件有数百行。我只是从那里抓取特定列以放入 Jinja2 模板中以生成配置。以上是关于从csv文件导入python时如何替换数字的主要内容,如果未能解决你的问题,请参考以下文章
将使用 PHP 创建的 csv 文件导入 Excel 时,如何在数字字符串值中保留前导零?
如何将导入 python 的数据从 csv 文件转换为时间序列?