Python将收集来的内网配置整理成IP-MAC列表

        为规范化员工上网行为,决定在路由器上设置IP-MAC绑定,一台机一个固定IP号,由DHCP自动发布。

        从局域网各台电脑中收集来的文本文件,内容是由如下DOS命令生成的:

ipconfig /all >d:\任意名.txt

        这些文件统一放在同一个目录中,现要提取其中的主机名、IP、MAC号,生成局域网电脑IP-MAC绑定列表。

'''
在指定目录下,有从局域网各台电脑中收集来的文本文件,内容是由如下DOS命令生成的:
ipconfig /all >d:\任意名.txt
    本程序的任务是:收集并整理这些文本文件,提取其中的主机名、IP、MAC号,生成局域网电脑IP-MAC绑定列表(用于DHCP)
'''
'''
思路:
1,获取指定目录下所有文本文件的路径及文件名,生成路径文件列表
2,按路径文件列表,逐一打开这些文件,遍历全文,
检查其中是否包含“主机名”:如果是,加入到计算机列表中。
3,按计算机列表,逐一打开这些文件,遍历全文,搜索‘主机名’、
'IPv4 地址'、'物理地址',每个文件存储成一条列表
4,将所有列表加入到一个大列表中
5,输出到文本文件
6,打开该文本文件,删除所有不必要的[],'等字符,‘主机名’、
'IPv4 地址'、'物理地址'之间以空格分隔,不同主机信息各占一行
'''

'''1,获取指定目录下所有文本文件的路径及文件名,生成路径文件列表'''
# 设置要获取文件列表的目录
import os

目录 = 'd:\\'
# 指定要获取的文件类型
文件类型 = '.txt'
# 保存路径文件列表
路径文件列表 = []
for 文件名 in os.listdir(目录):
    # os.listdir(路径) 方法用于
    # 返回指定的文件夹里包含的文件或文件夹的名字的列表
    路径文件 = os.path.join(目录, 文件名)
    # os.path.join(路径名1,路径名2,路径名n)函数用于
    # 连接两个或更多的路径名
    # 如果各路径名首字母不包含'/',则函数会自动加上
    # 如果有一个路径名是一个绝对路径,则在它之前的所有路径名均会被舍弃
    # 如果最后一个路径名为空,则生成的路径以一个'/'分隔符结尾
    if (os.path.isfile(路径文件) and 路径文件[-4:].lower() == 文件类型):
        # os.path.isfile(路径文件):判断某一对象(需提供绝对路径)是否为文件
        # 拓展:os.path.isdir(路径):判断某一对象(需提供绝对路径)是否为目录
        # 路径文件[-4:]:拓展名.txt是从索引号-4到字符串末尾
        路径文件列表.append(路径文件)
print(路径文件列表)

'''
2,按路径文件列表,逐一打开这些文件,遍历全文,
        检查其中是否包含“主机名”:如果是,加入到计算机列表中
'''
查找主机 = '主机名'
计算机列表 = []
for 目录 in 路径文件列表:
    with open(目录, 'r', encoding='utf-8', errors='ignore') as 文件:
        '''
        这里需要预先对所有收集来的文本文件进行预处理,转码成为utf-8
        可以用UltraEdit的程序员环境,左侧的资源管理器里找到文本文件的
        存放目录,按shift选择要转码的文件,菜单:文件→转换→
        ASCII转UTF-8(UniCode编辑)
        '''
        # errors='ignore'代表如果不能用encoding指定的编码格式打开,就忽略它
        文件内容 = 文件.read()
        # read()方法一次性读取文件所有内容到变量“文件内容”中
        if 查找主机 in 文件内容:
            计算机列表.append(目录)
print(计算机列表)

'''
3,按计算机列表,逐一打开这些文件,遍历全文,搜索‘主机名’、
'IPv4 地址'、'物理地址',每个文件存储成一条列表
'''
查找IP = 'IPv4 地址'
查找网卡 = '物理地址'
临时电脑信息列表 = []
局域网电脑列表 = []
for 目录 in 计算机列表:
    with open(目录, 'r', encoding='utf-8', errors='ignore') as 文件:
        for 行数 in 文件:
            行内容 = 文件.readline()
            if 查找主机 in 行内容:
                索引 = 行内容.find(': ') + 2
                # 变量‘行’的内容其实是一个字符串,可以当作列表来处理
                # 由于搜索的关键词': '后有空格,故索引号+2
                '''
                find()方法:
                find(要查找的字符串,开始索引默认0,结束索引默认-1末尾)
                检测字符串中是否包含'要查找的字符串',
                如果指定'开始索引'和'结束索引'范围,
                则检查是否包含在指定范围内;
                如果包含子字符串返回开始的索引值,否则返回-1
                '''
                临时电脑信息列表.append(行内容[索引:-1])
            elif 查找网卡 in 行内容:
                索引 = 行内容.find(': ') + 2
                网卡 = 行内容[索引:-1]
                临时电脑信息列表.append(网卡)
                # 例:物理地址. . . . . . . . . . . . . : E0-D5-5E-D6-7A-CA
            elif 查找IP in 行内容:
                前索引 = 行内容.find(': ') + 2
                后索引 = 行内容.find('(首选)')
                # print (行内容[前索引:后索引])
                临时电脑信息列表.append(行内容[前索引:后索引])
                # 因为这回要截取的是字符串的中间部分,而不是到末尾,例:
                # IPv4 地址 . . . . . . . . . . . . : 192.168.0.21(首选)
        '''4,将所有列表加入到一个大列表中'''
        局域网电脑列表.append(临时电脑信息列表)
        临时电脑信息列表 = []
        # 清空临时电脑信息列表

'''5,输出到文本文件'''
import sys

# 设置要删除的标点符号列表,不能直接用"for 标点 in string.punctuation:"
# 因为string.punctuation包含了'.'与‘-’号,而IP与网卡号需要保留它们
要删除的符号 = ["[", "]", ",", "'"]
# 调入系统模块
写入文件路径 = 'd:\\临时转存列表.txt'
with open(写入文件路径, 'w', encoding='utf-8') as 文件:
    sys.stdout = 文件
    # .stdout:标准输出,将下面的打印内容输出到文本文件中
    for 变量 in 局域网电脑列表:
        print(变量)
'''
6,打开该文本文件,删除所有不必要的[], '等字符,‘主机名’、
    'IPv4 地址'、'物理地址'
    之间以空格分隔,不同主机信息各占一行
'''
最终结果文件 = 'd:\\局域网电脑列表.txt'
# 设置要删除和标点符号列表
要删除的符号 = ["[", "]", ",", "'"]
# 不能直接用'for 标点 in string.punctuation:'
# 因为string.punctuation包含‘.’和‘-’,IP和MAC需要保留它们
with open(写入文件路径, 'a+', encoding='utf-8') as 文件:
    sys.stdout = 文件
    '''
    执行sys.stdout=文件之后,对“文件”的任何操作也将对sys.stdout执行。
    离开with块会关闭“文件”,因此它也会关闭sys.stdout。然后,当您稍后
    执行print时,它尝试将此写入sys.stdout,但它已关闭,因此会得到一
    个错误:ValueError: I/O operation on closed file。
    所以打开第二个文件后,需要再次使用sys.stdout=文件
    '''
    with open(最终结果文件, 'w', encoding='utf-8') as 结果:
        '''
        多了这步with open实属无奈,找不到python打开文件直接编辑的功能
        只能新开一个文件,将从原文件中读到的内容经修改后,写到新文件
        各位若有好办法,还望赐教
        '''
        sys.stdout = 结果
        文件.seek(0)
        '''
        因为上面的“with open(写入文件路径,'a+',encoding='utf-8')as 文件:”
        中使用的是“a+”,以读写模式打开文件,指针在文件尾。故要将其
        复位到文件头,否则下面的read()方法读不到内容
        '''
        内容 = 文件.read()
        # 将从原文件读到的内容进行修改(替换标点)并写入新文件
        for 标点 in 要删除的符号:
            内容 = 内容.replace(标点, '')
        print(内容)

# 删除临时文件
os.remove(写入文件路径)
# 打开目录
os.startfile('d:\\')
# 用操作系统默认程序打开上述文件
os.startfile(最终结果文件)

'''写在后面的话
用表格处理软件(如EXCEL)导入d:\局域网电脑列表.txt文件时,以空格
为间隔标志,各行的导入类型设为“文本”,以防又出现科学计数法
因我是初学者,以学习为目的,受限于个人水平,这段代码反复遍历、
反复打开文件,反复写文件,这些效率都很低下,肯定有很大的改善空间
各位若有更高效的方法,还望不吝赐教
'''

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

将出东方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值