从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, in re.findall (pattern, test_value) NameError: name 'test_value' is not defined 不用担心 - 我只是输入了一个通用变量名称 test_value 但您想用存储要从中提取桥域的每一行的变量替换它 意志。我对编程很陌生。我没有完全理解。所需的变量是否在 for 循环中定义?变量将等于什么?请帮我理解。 没关系 - 我不确定在不知道 csv 文件的内容和模板的情况下是否能够真正帮助您,以了解您如何操作 csv 文件的每一行。但基本上听起来您可能需要另一个循环来遍历list_elements 的每个元素并在每一行上运行匹配以提取桥 ID,然后将其替换为所需格式的 ID。也就是说,如果我从您提供的输出中正确猜到了您的模板在做什么。 即csv文件的列标题和一行。 CSV 文件有数百行。我只是从那里抓取特定列以放入 Jinja2 模板中以生成配置。

以上是关于从csv文件导入python时如何替换数字的主要内容,如果未能解决你的问题,请参考以下文章

将使用 PHP 创建的 csv 文件导入 Excel 时,如何在数字字符串值中保留前导零?

如何将导入 python 的数据从 csv 文件转换为时间序列?

几个CSV大文件如何导入mysql数据库,并更新替换对应数据?

如何从 CSV 文件导入数据并将其存储在变量中?

Python - 导入csv文件并按列分组数字

从 CSV 文件导入包含逗号的变量