如何替换文件中的单词/数字

时间:2019-03-16 10:00:40

标签: python python-3.x

我正在尝试用私有文件替换文件中的全局IP并创建它们的映射,因此即使新字符串的一部分不同,我也可以将其还原。 我陷入了用虚假IP替换全局IP并将其写入文件的问题。

起始文件示例:

ip route 192.168.1.0 255.255.0.0 10.10.10.2
ip route 192.168.1.0 255.255.0.0 1.1.1.2
ip route 1.1.1.1 255.255.0.0 1.1.1.3
interface FastEthernet1
ip address 1.1.1.1
duplex auto
speed auto

想要最终结果,某些措辞可能会有所变化,然后再还原:

ip route ipv4 192.168.1.0 255.255.0.0 10.10.10.2
ip route ipv4 192.168.1.0 255.255.0.0 10.1.1.11
ip route ipv4 10.1.1.10 255.255.0.0 10.1.1.12
interface FastEthernet1
ip address 10.1.1.10
duplex auto
speed auto

我所映射的是这样的字典:

mapping = {
    '1.1.1.2': "10.1.1.10", 
    '1.1.1.1': "10.1.1.10", 
    '1.1.1.3': "10.1.1.30
    }

直到现在,我才使用此脚本,但是它没有达到我想要的效果:

import re
import ipaddress


def load_file(file) -> str:
    with open(file, 'r') as f:
        return f.read()


def find_ips(config) -> set:
    ip_regex = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
    match = set(re.findall(ip_regex, config))
    return match


def mapping_ip(ips) -> dict:
    counter = 0
    ip_table = {}
    for ip in ips:
        ip4_type = ipaddress.IPv4Address(ip)

        if ip4_type.is_global:
            counter += 1
            private = ipaddress.IPv4Address('10.1.1.10') + counter
            ip_table.update({
                ip: str(private),
                })
    return ip_table


def replace(mapping, s_file, d_file):
    with open(s_file, 'r') as reader, open(d_file, 'w') as writer:
        for line in reader:
            for orig, temp in mapping.items():
                if orig in line:
                    x = line.replace(orig, temp)
                    writer.write(x)

关于我应该如何进行替换功能的任何建议? 只有IP可以更改,字符串的其余部分需要保持原样(返回过程)。

2 个答案:

答案 0 :(得分:1)

您可以在源文件的行上简单地使用字符串替换:

创建源文件:

t = """ip route 192.168.1.0 255.255.0.0 10.10.10.2
ip route 192.168.1.0 255.255.0.0 1.1.1.2
ip route 1.1.1.1 255.255.0.0 1.1.1.3
interface FastEthernet1
ip address 1.1.1.1
duplex auto
speed auto"""

with open("t.txt","w") as f: 
    f.write(t)

替换内容并写入"mod.txt"

mapping = {
    '1.1.1.2': "10.1.1.10", 
    '1.1.1.1': "10.1.1.10", 
    '1.1.1.3': "10.1.1.30"
    }

with open("mod.txt","w") as m, open("t.txt") as data:
    for line in data:
        for key,replacewith in mapping.items():
            line = line.replace(key,replacewith)
        m.write(line)

with open("mod.txt") as f:
    print(f.read()) 

输出:

ip route 192.168.1.0 255.255.0.0 10.10.10.2
ip route 192.168.1.0 255.255.0.0 10.1.1.10
ip route 10.1.1.10 255.255.0.0 10.1.1.30
interface FastEthernet1
ip address 10.1.1.10
duplex auto
speed auto

这将尝试m次替换每行(m == len(mapping)),并且由于创建了许多中间字符串(如果替换了某些东西),因此速度不是很快-这是一个更棘手的解决方案解决您的问题。

答案 1 :(得分:0)

在这种情况下,您可以按照以下方式利用re.sub

import re
txt = 'ip route 192.168.1.0 255.255.0.0 10.10.10.2\nip route 192.168.1.0 255.255.0.0 1.1.1.2\nip route 1.1.1.1 255.255.0.0 1.1.1.3\ninterface FastEthernet1\nip address 1.1.1.1\nduplex auto\nspeed auto'
out = re.sub(r'1\.1\.1\.([1-3])','10.1.1.\g<1>0',txt)
print(out)

输出:

ip route 192.168.1.0 255.255.0.0 10.10.10.2
ip route 192.168.1.0 255.255.0.0 10.1.1.20
ip route 10.1.1.10 255.255.0.0 10.1.1.30
interface FastEthernet1
ip address 10.1.1.10
duplex auto
speed auto

为简单起见,我对txt进行了硬编码,最重要的一行是re.sub的那一行:

out = re.sub(r'1\.1\.1\.([1-3])','10.1.1.\g<1>0',txt)

它用第二个参数替换匹配第一个参数的txt的子字符串,第一个参数包含一个组([1-3]),随后在第二个参数(\g<1>)中引用它,因此实际上执行以下替换:

1.1.1.110.1.1.10

1.1.1.210.1.1.20

1.1.1.310.1.1.30

但是请记住,re.sub以单遍方式工作,与重复使用.replace的{​​{1}}方法不同。