五、Python3自动化运维_业务监控之目录对比

本文详细介绍了Python的filecmp模块用于文件和目录的对比,包括单文件对比、多文件对比和目录对比,并展示了如何批量创建嵌套目录。通过案例演示了如何校验源与备份目录的差异,实现文件同步,包括目录创建和文件复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础知识

简介

为了保证 留存的文件是我们需要的,所以,我们再保存后的文件,做一个唯一的标识符,然后再次使用的时候,检查文件的位移标识符,如果是一致的,说明文件在这期间没有任何变动,说明安全,否则,说明文件发生异常变动。

工具

filecmp
各种嵌套文件的 信息对比 情况

场景

系统安全
文件变动
备份安全

模块详解

模块简介

定位
文件信息的比对
组成
cmp 单文件信息对比
cmpfiles 多文件信息对比
dircmp 目录文件信息对比

单文件对比

基础知识:查看文件的属性
ls 查看文件列表
ll 查看列表的时候,展示属性信息
lsattr 查看文件的一些扩展属性
file 查看文件类型
stat 查看文件状态信息
在这里插入图片描述
模块解析:
filecmp.cmp(文件1,文件2,[shallow=True|False])
shallow=True表示使用sys.stat对比文件属性
False表示在True的基础上,增加对内容的比对
注意:
属性的比较,主要以 修改的时间 属性为基准。
准备工作:
在这里插入图片描述在这里插入图片描述文件属性对比:
在这里插入图片描述
在这里插入图片描述
文件基本属性比较
在这里插入图片描述
查看文件后效果比较 - bashrc2
在这里插入图片描述
结果显示,cmp对比文件属性,不是以访问时间为对比
在这里插入图片描述
修改文件:
在这里插入图片描述
在这里插入图片描述

多文件对比

方法简介:
filecmp.cmpfiles(目录1,目录2,common[shallow=True|False])
shallow=True 表示 使用sys.stat对比文件属性
False 表示 在True的基础上,增加对内容的比对
注意:
结果相对于cmp来说,不是True和False,而是三个列表,一致的列表、不一致的列表、无法比对列表。

	一致的列表		属性一致
	不一致的列表	属性不一致
	无法比对列表,未知原因导致,无法进行文件比较或者属性获取

目录的状态详情
在这里插入图片描述
md5sum命令解析:
md5sum
基于文件的属性(不是内容)信息,生成唯一的标识符,也叫校验码 | 和
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
准备相同的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
多文件比较效果:
在这里插入图片描述

目录对比

sudo apt install tree -y
例 tree /tmp/

基础语法
filecmp.dircmp(目录1,目录2,ignore,hide)
ignore 表示可以忽略的对比文件
hide 表示可以隐藏的文件列表
注意:
三种输出结果报告
report 仅当前目录
report_partial_closure 当前目录及下一级子目录
report_all_closure 所有的目录结构
在这里插入图片描述

如何批量创建嵌套结构的目录:

mkdir{dir1,dir2,dir3/sub1} 	-p

创建代码:

mkdir dir1/{a,f1,f2,f3,f4}
mkdir dir1/{a,f1,f2,f3,f4} -p
mkdir dir1/a/{a1,b/{b1,b2,b3}} -p
touch dir1/test.py
mkdir dir2/{a/{a1,b/{b1,b2,b3}},aa/aa1,f1,f2,f3,f5} -p
touch dir2/test.py

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
简单实践
思路:
1 准备环境(已准备)
2 定制目录比较
2-1 定制目录位置 在这里插入图片描述
2-2 实现目录的比对,忽略掉普通文件
在这里插入图片描述
3 输出报告
3-1 仅输出当前目录下的效果
dir_object.report()
3-2 仅输出当前目录及一级目录下的效果
dir_object.report_partial_closure()
3-3 输出所有目录信息的效果
dir_object.report_full_closure()

	4 查看详情
		4-1 查询属性信息
		print("左目录:{}".format(dir_object.left))
		print("信息格式:{}".format(type(dir_object.left)))
		4-2 属性信息查看
		print("左目录:{}".format(dir_object.left))
		print("右目录:{}".format(dir_object.right))
		print("仅左目录:{}".format(dir_object.left_only))
		print("仅右目录:{}".format(dir_object.right_only))
		print("共同目录:{}".format(dir_object.common))
		print("无法比较文件:{}".format(dir_object.funny_files))

在这里插入图片描述

综合案例:校验源与备份目录差异

在这里插入图片描述

需求简介

简介
文件的同步场景
新文件同步
老文件更新
如果同步失败或者更新失误:
针对性的检查,并进行同步或者更新
在这里插入图片描述
思路:
内容的针对性判断 - - filecmp
left_only 项目源目录仅有的 - - 同步失败的新文件
diff_files 项目源目录中内容不一致的 - - 更新失败的文件
内容的复制和同步
shutil.copyfile - - 文件的同步
os.makedir - - 新目录的创建
原则
1 导模块
- - 分析使用了哪些功能模块
2 看方法
- - 看一下主要有哪些业务组成
3 主函数
- - 看一下业务逻辑的流程
代码分析:
在这里插入图片描述
在这里插入图片描述
思路:
文件对比思路
1 接收两个目录
2 对目录仅简单的比对,并获取失败的内容
3 列表推导式,临时存储一级异常目录
4 递归方式,对子目录进行文件对比测试
5 返回最终的不匹配目录或者文件
主函数代码 - 代码思路:
1 接收脚本执行时候的参数
argv[1]和argv[2]
2 获取所有的源目录结果信息
compareme 方法的使用
3 如果是新目录,则进行创建
属性更改的 目标文件列表
创建对应的目录
4 如果是普通文件,则进行简单复制
将源文件和目标文件组合对
然后使用 copy 的方法创建
在这里插入图片描述
在这里插入图片描述

代码实践1

在这里插入图片描述
应该返回f4

"""
文件备份案例实践
"""
# 导包
import os,sys
import filecmp
import re
import shutil

# 临时的文件列表
hoderlist=[]
# 1 文件比对方法
def compareme(dir1,dir2):
    """
    对文件目录进行比对,获取所有的文件信息
    :param dir1:源代码目录结构
    :param dir2:目标目录结构
    :return: hoderlist 返回统计后的文件目录列表
    """
    # 1 对两个目录进行比较
    dircomp = filecmp.dircmp(dir1,dir2)
    # 2 获取需要同步的信息
    only_in_one = dircomp.left_only
    diff_in_one = dircomp.diff_files
    # 3 更新临时存储的文件列表  所在的目录
    # 3-1 获取绝对路径
    dirpath = os.path.abspath(dir1)
    # 3-2 获取左侧唯一的内容
    [hoderlist.append(os.path.abspath(os.path.join(dir1,x))) for x in only_in_one]
    # 3-3 获取左侧不匹配的内容
    [hoderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one]
    # 4 递归方式获取所有文件信息
    if len(dircomp.common_files) > 0:
        # 4-1 遍历所有的子目录
        for item in dircomp.common_dirs:
            # 4-2 对所有的子目录进行内容比对 - 使用方法本身
            compareme(os.path.abspath(os.path.join(dir1,item)),os.path.abspath(os.path.join(dir2,item)))

    # 5 返回更新后的文件列表
        return hoderlist

# 2 主函数方法
def main():
    pass

# 3 执行
if __name__ == '__main__':
    # 临时测试 对比 /home/python/dir1 和 /home/python/dir2 返回应该是f4
    result = compareme('/home/user1/dir1','/home/user1/dir2')
    print("待同步的源目录下的文件有:{}".format(result))

输出结果为

待同步的源目录下的文件有:['/home/user1/dir1/f4']

代码实践2 - 主函数

代码内容

"""
文件备份案例实践
"""
# 导包
import os,sys
import filecmp
import re
import shutil

# 临时的文件列表
hoderlist=[]
# 1 文件比对方法
def compareme(dir1,dir2):
    """
    对文件目录进行比对,获取所有的文件信息
    :param dir1:源代码目录结构
    :param dir2:目标目录结构
    :return: hoderlist 返回统计后的文件目录列表
    """
    # 1 对两个目录进行比较
    dircomp = filecmp.dircmp(dir1,dir2)
    # 2 获取需要同步的信息
    only_in_one = dircomp.left_only
    diff_in_one = dircomp.diff_files
    # 3 更新临时存储的文件列表  所在的目录
    # 3-1 获取绝对路径
    dirpath = os.path.abspath(dir1)
    # 3-2 获取左侧唯一的内容
    [hoderlist.append(os.path.abspath(os.path.join(dir1,x))) for x in only_in_one]
    # 3-3 获取左侧不匹配的内容
    [hoderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one]
    # 4 递归方式获取所有文件信息
    if len(dircomp.common_files) > 0:
        # 4-1 遍历所有的子目录
        for item in dircomp.common_dirs:
            # 4-2 对所有的子目录进行内容比对 - 使用方法本身
            compareme(os.path.abspath(os.path.join(dir1,item)),os.path.abspath(os.path.join(dir2,item)))

    # 5 返回更新后的文件列表
        return hoderlist

# 2 主函数方法
def main():
    # 1 准备工作
    # 1-1 接收两个脚本参数及脚本的使用方式
    if len(sys.argv) > 2:
        dir1 = sys.argv[1]
        dir2 = sys.argv[2]
    else:
        print("脚本的使用方式:脚本名 目录1 目录2")
        sys.exit()
    # 1-2 目录的准备工作
    source_files = compareme(dir1,dir2) # 获取待同步的目录
    dir1 = os.path.abspath(dir1)    # 获取待同步的目录位置
    destination_files = []      # 要同步的目录路径
    createdir_bool = False      # 新增目录的时候,设定的标识符


    # 2 目录创建
    # 2-1 获取待同步的所有目录结构 - 通过替换的方式实现目标目录的确定
    # 这是已存在的目录内容同步
    for item in source_files:
        # 目标目录的列表同步
        destination_dir = re.sub(dir1,dir2,item)
        destination_files.append(destination_dir)
        # 对目标目录进行简单的判断,如果不存在就创建
        if os.path.isdir(item):
            if not os.path.exists(destination_dir):
                os.makedirs(destination_dir)
                createdir_bool = True
    # 2-2 同步目录 - 必须保证临时目录createdir_bool是True
    # 这是刚才新建的目录内容同步
    if createdir_bool:
        destination_files = []
        source_files = []
        source_files = compareme(dir1,dir2)
        for item in source_files:
            destination_dir = re.sub(dir1,dir2,item)
            destination_files.append(destination_dir)

    # 3 文件的同步
    # 3-1 提示同步更新
    print("更新item:")
    print("需要同步的文件:{}".format(source_files))
    # 3-2 便于cp命令的实现,我们将源文件路径和目标文件路径生成数据对
    copy_pair = zip(source_files,destination_files)
    # 3-3 开始进行数据的复制
    for item in copy_pair:
        if os.path.islife(item[0]):
            shutil.copyfile(item[0],item[1])
            # 样式:cp file1 file2

# 3 执行
if __name__ == '__main__':
    main()

实践1 - 脚本的使用 (不给参数,直接run)
在这里插入图片描述
实践2 - 目录的同步创建

rm -r /home/user1/dir2/f4

在这里插入图片描述
使用pycharm执行命令的时候 添加执行参数,两个参数中间必须加空格!:
在这里插入图片描述

"""
文件备份案例实践
"""
# 导包
import os,sys
import filecmp
import re
import shutil

# 临时的文件列表
hoderlist=[]
# 1 文件比对方法
def compareme(dir1,dir2):
    """
    对文件目录进行比对,获取所有的文件信息
    :param dir1:源代码目录结构
    :param dir2:目标目录结构
    :return: hoderlist 返回统计后的文件目录列表
    """
    # 1 对两个目录进行比较
    dircomp = filecmp.dircmp(dir1,dir2)
    # 2 获取需要同步的信息
    only_in_one = dircomp.left_only
    diff_in_one = dircomp.diff_files
    # 3 更新临时存储的文件列表  所在的目录
    # 3-1 获取绝对路径
    dirpath = os.path.abspath(dir1)
    # 3-2 获取左侧唯一的内容
    [hoderlist.append(os.path.abspath(os.path.join(dir1,x))) for x in only_in_one]
    # 3-3 获取左侧不匹配的内容
    [hoderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one]
    # 4 递归方式获取所有文件信息
    if len(dircomp.common_files) > 0:
        # 4-1 遍历所有的子目录
        for item in dircomp.common_dirs:
            # 4-2 对所有的子目录进行内容比对 - 使用方法本身
            compareme(os.path.abspath(os.path.join(dir1,item)),os.path.abspath(os.path.join(dir2,item)))

    # 5 返回更新后的文件列表
        return hoderlist

# 2 主函数方法
def main():
    # 1 准备工作
    # 1-1 接收两个脚本参数及脚本的使用方式
    if len(sys.argv) > 2:
        dir1 = sys.argv[1]
        dir2 = sys.argv[2]
    else:
        print("脚本的使用方式:脚本名 目录1 目录2")
        sys.exit()
    # 1-2 目录的准备工作
    source_files = compareme(dir1,dir2) # 获取待同步的目录
    dir1 = os.path.abspath(dir1)    # 获取待同步的目录位置
    destination_files = []      # 要同步的目录路径
    createdir_bool = False      # 新增目录的时候,设定的标识符


    # 2 目录创建
    # 2-1 获取待同步的所有目录结构 - 通过替换的方式实现目标目录的确定
    # 这是已存在的目录内容同步
    for item in source_files:
        # 目标目录的列表同步
        destination_dir = re.sub(dir1,dir2,item)
        destination_files.append(destination_dir)
        # 对目标目录进行简单的判断,如果不存在就创建
        if os.path.isdir(item):
            if not os.path.exists(destination_dir):
                os.makedirs(destination_dir)
                createdir_bool = True
    # 2-2 同步目录 - 必须保证临时目录createdir_bool是True
    # 这是刚才新建的目录内容同步
    if createdir_bool:
        destination_files = []
        source_files = []
        source_files = compareme(dir1,dir2)
        for item in source_files:
            destination_dir = re.sub(dir1,dir2,item)
            destination_files.append(destination_dir)

    # 3 文件的同步
    # 3-1 提示同步更新
    print("更新item:")
    print("需要同步的文件:{}".format(source_files))
    # 3-2 便于cp命令的实现,我们将源文件路径和目标文件路径生成数据对
    copy_pair = zip(source_files,destination_files)
    # 3-3 开始进行数据的复制
    for item in copy_pair:
        if os.path.isfile(item[0]):
            shutil.copyfile(item[0],item[1])
            # 样式:cp file1 file2

# 3 执行
if __name__ == '__main__':
    main()

结果:

更新item:
需要同步的文件:['/home/user1/dir1/f4']

运行前
在这里插入图片描述
运行后:
在这里插入图片描述
实践3 - 在一个子目录下生成文件
在这里插入图片描述
在这里插入图片描述
思考:
如何一步到位,将多层子目录全部同步完毕,然后将所有的文件同步成功
- - 在比对的时候,做while 循环即可
- - 就是目录创建
此步没有代码,自行实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值