文件与目录差异对比方法

简介:

环境:

Python 2.6.6

linux系统


用到的模块:filecmp

filecmp提供了:单文件对比,多文件对比,目录对比


单文件对比:采用filecmp.cmp(f1,f2[,shallow])方法,比较文件名为f1和f2的文件的内容,相同返回True,不相同返回False,shallow默认是True,意思是只根据os.stat()方法返回的文件基本信息进行对比,比如最后访问时间、修改时间、状态改变时间等,会忽略文件内容的对比。当shallow为False时,则os.stat()与文件内容同时进行校验。


例子:

1
2
3
4
5
>>>  import  filecmp
>>> filecmp. cmp ( "/root/dir1/f1" , "/root/dir2/f1" )
True
>>> filecmp. cmp ( "/root/dir1/f1" , "/root/dir2/f5" )
False

多文件对比:采用filecmp.cmpfiles(dir1, dir2, common[, shallow])方法,对比dir1与dir2目录给定的文件清单。该方法返回文件名的三个列表,分别为匹配、不匹配、错误。匹配为包含匹配的文件的列表,不匹配反之,错误列表包括了目录不存在文件、不具备读权限或其他原因导致的不能比较的文件清单。

例子:

先建立一些文件:

wKiom1mylGnxXlP4AABAULk2v-A832.png

代码:

1
2
>>> filecmp.cmpfiles( "/root/dir1" , "/root/dir2" ,[ 'f1' , 'f2' , 'f3' , 'f4' , 'f5' ])
([ 'f1' 'f2' 'f3' 'f4' ], [], [ 'f5' ])


目录对比:通过dircmp(a, b[, ignore[, hide]])类创建一个目录比较对象,其中a和b是参加比较的目录名。ignore代表文件名忽略的列表,并默认为['RCS', 'CVS', 'tags'];hide代表隐藏的列表,默认为[os.curdir,os.pardir]。dircmp类可以获得目录比较的详细信息,如只有在a目录中包括的文件、a与b都存在的子目录、匹配的文件等,同时支持递归。


例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python
#-*—coding:utf-8-*-
#2017,9,7
 
import  filecmp
 
=  "/root/dir1"  #定义左目录
=  "/root/dir2"  #定义右目录
 
dirobj  =  filecmp.dircmp(a,b,[ '1.py' ])  #目录比较,忽略1.py文件。
 
dirobj.report()  #比较当前指定目录中的内容
dirobj.report_full_closure()  #递归比较所有指定目录的内容
dirobj.report_partial_closure()  #比较当前指定目录以及第一级目录中的内容
 
print  "_" * 50
print  "left_list:"  +  str (dirobj.left_list)  #左目录
print  "_" * 50
print  "right_list:" + str (dirobj.right_list)  #右目录
print  "_" * 50
print  "commom:" + str (dirobj.common)  #两边共同存在的目录
print  "_" * 50
print  "left_only:" + str (dirobj.left_only)  #只在左目录中的文件或者目录
print  "_" * 50
print  "right_only:" + str (dirobj.right_only)   #只在右目录中的文件或者目录
print  "_" * 50
print  "common_dirs:" + str (dirobj.common_dirs) #两边目录都存在的子目录
print  "_" * 50
print  "common_files:" + str (dirobj.common_files)  #两边目录都存在的文件
print  "_" * 50
print  "common_funny:" + str (dirobj.common_funny)  #两边目录都存在的目录
print  "_" * 50
print  "same_files:" + str (dirobj.same_files)  #匹配相同的文件
print  "_" * 50
print  "diff_files:"  +  str (dirobj.diff_files)  #不匹配的文件
print  "_" * 50
print  "funny_files:"  +  str (dirobj.diff_files)  #两边目录中都存在,但是无法比较的文件

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
diff  /root/dir1  /root/dir2
Only  in  /root/dir2  : [ 'f5' ]
Identical files : [ 'f1' 'f2' 'f3' 'f4' ]
diff  /root/dir1  /root/dir2
Only  in  /root/dir2  : [ 'f5' ]
Identical files : [ 'f1' 'f2' 'f3' 'f4' ]
diff  /root/dir1  /root/dir2
Only  in  /root/dir2  : [ 'f5' ]
Identical files : [ 'f1' 'f2' 'f3' 'f4' ]
__________________________________________________
left_list:[ 'f1' 'f2' 'f3' 'f4' ]
__________________________________________________
right_list:[ 'f1' 'f2' 'f3' 'f4' 'f5' ]
__________________________________________________
commom:[ 'f1' 'f2' 'f3' 'f4' ]
__________________________________________________
left_only:[]
__________________________________________________
right_only:[ 'f5' ]
__________________________________________________
common_dirs:[]
__________________________________________________
common_files:[ 'f1' 'f2' 'f3' 'f4' ]
__________________________________________________
common_funny:[]
__________________________________________________
same_files:[ 'f1' 'f2' 'f3' 'f4' ]
__________________________________________________
diff_files:[]
__________________________________________________
funny_files:[]


实践:效验源与备份目录差异

源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/env python
#coding:utf-8
#2017,9,7
 
import  os
import  sys
import  filecmp
import  re
import  shutil
 
holderlist = []
 
def  compareme(dir1,dir2):
         dircomp  =  filecmp.dircmp(dir1,dir2)
         only_in_one  =  dircomp.left_only  #源目录新文件或目录(只在左目录中的文件或者目录)
         diff_in_one  =  dircomp.diff_files  #不匹配文件,源目录文件已经发生变化
         dirpath  =  os.path.abspath(dir1)  #获取源目录的绝对路径。
         #将更新文件名或者目录追加到holderlist
         [holderlist.append(os.path.abspath(os.path.join(dir1,x)))  for  in  only_in_one]
         [holderlist.append(os.path.abspath(os.path.join(dir1,x)))  for  in  diff_in_one]
         if  len (dircomp.common_dirs) >  0 :
                 for  item  in  dircomp.common_dirs:
         return  holderlist
 
 
def  main():
         if  len (sys.argv) >  2 :
                 dir1  =  sys.argv[ 1 ]
                 dir2  =  sys.argv[ 2 ]
         else :
                 print  "usage:" ,sys.argv[ 0 ], "datadir backupdir"
                 sys.exit()
         source_files  =  compareme(dir1,dir2)  #对比源目录与备份目录
         dir1  =  os.path.abspath(dir1)
 
         if  not  dir2.endswith( '/' ):
                 dir2  =  dir2 + '/'
         dir2  =  os.path.abspath(dir2)
         destination_files  =  []
         createdir_bool  = False
 
         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  #再一次调用compareme函数标记
         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)
         print  "updata item:"
         print  source_files  #输出更新列表清单
         copy_pair  =  zip (source_files,destination_files)  #将源目录与备份目录文件拆分成元组
         for  item  in  copy_pair:
                 if  os.path.isfile(item[ 0 ]):  #判断是否为文件,是则进行复制
                         shutil.copyfile(item[ 0 ],item[ 1 ])
 
 
 
if  __name__ = = '__main__' :
         main()

执行结果:

wKiom1myllng5ONdAAAn_dj3n2c260.png


总结\注意\拓展:


总结:

本次学习不仅学会了文件备份的效验,而且学习到了一个语法:

1
2
3
4
  [holderlist.append(os.path.abspath(os.path.join(dir1,x)))  for  in  only_in_one]
  #正常写法
  for  in  only_in_one:
      holderlist.append(os.path.abspath(os.path.join(dir1,x)))

注意:

在写程序的时候一定要注意缩进,不然容易报错,我在写下面这句的时候就老报语法错误,做后让别人打一遍,我复制一下才成功:

1
return  holderlist


拓展:

re.sub是re模块重要的组成部分,并且功能也非常强大,主要功能实现正则的替换

re.sub定义: 
sub(pattern, repl, string, count=0, flags=0)


解释:

pattern:为表示正则中的模式字符串, 
repl为replacement,被替换的内容,repl可以是字符串,也可以是函数。 
string为正则表达式匹配的内容。 
count:由于正则表达式匹配到的结果是多个,使用count来限定替换的个数(顺序为从左向右),默认值为0,替换所有的匹配到的结果。 
flag是匹配模式,可以使用按位或’|’表示同时生效,也可以在正则表达式字符串中指定。

例子:

1
2
3
>>> import  re
>>>re.sub(r '\w+' , '10' , "ji 43 af,geq" , 2 ,flags = re.I)
>>> '10 10 af,geq'


shutil模块:

详情参考:http://blog.csdn.net/xmnathan/article/details/36217631



参考链接1:https://book.2cto.com/201411/48243.html

参考链接2:http://blog.csdn.net/hjxzt1/article/details/73741507

参考资料1:百度知道

参考资料2:网络资源

参考资料3:《Python自动化运维技术与最佳实践》-刘天斯 著


wKiom1myl5zgGMuPAAQF1aT1ixQ567.png



本文转自 天道酬勤VIP 51CTO博客,原文链接:http://blog.51cto.com/tdcqvip/1963827


相关文章
|
3月前
|
SQL 人工智能 分布式计算
大厂面试官最看重的大数据证书:让你的简历脱颖而出
不要只说"我考了XX证",要结合证书项目讲解:"在准备CCP认证时,我通过优化Hive查询将ETL任务耗时从4小时缩短到27分钟,这个方案后来被应用到..."
|
9月前
|
安全 架构师 数据管理
《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》简介
《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》由北京大学出版社出版,内容涵盖HarmonyOS架构、DevEco Studio、Ability、安全管理等,辅以68个实例和4个综合实战案例。全书589页,定价129元,适合学生、开发人员及架构师。封面延续黑色设计,配以蓝色“鸿蒙HarmonyOS”字样,富有科技感。本书紧跟最新技术,提供源代码下载和勘误交流平台,帮助读者掌握HarmonyOS开发技能,构建万物互联的新时代。
317 22
SOUL私信群发工具,全自动关注点赞私信脚本,无限制按键深度定制版
这是一款针对SOUL平台开发的自动化营销脚本,可通过模拟用户行为实现批量私信功能,帮助将流量导入私域并转化。脚本支持自定义搜索关键词
|
6月前
|
存储 监控 安全
课时17:阿里云智能制造解决方案:从中国制造到中国智造
阿里云智能制造解决方案融合云计算、大数据和人工智能,提供一站式设备接入管理,助力工业客户实现从“中国制造”到“中国智造”的跨越。通过解决数据孤岛、实时数据分析和智能算法,方案提升生产效率与良品率,降低运营成本,并确保信息安全。此外,支持远程监控与定制化服务,全面推动产业升级与创新。
190 0
|
存储 机器学习/深度学习 SQL
【Prompt Engineering:自我反思(Reflexion)】
自我反思(Reflexion)是一种通过语言反馈强化基于语言的智能体的新范式,无需微调模型即可提升其在决策、推理和编程等任务中的表现。该框架包括参与者(生成动作)、评估者(评分)和自我反思(生成反馈)三个部分,利用大语言模型生成具体反馈,帮助智能体从错误中快速学习,显著提高了多种任务的性能。
1165 2
【Prompt Engineering:自我反思(Reflexion)】
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
AI在自然语言处理中的突破:从理论到应用
AI在自然语言处理中的突破:从理论到应用
387 17
|
9月前
|
消息中间件 缓存 PHP
PHP性能优化:从基础到进阶的实战指南####
本文旨在为开发者提供一份全面的PHP性能优化指南,涵盖从代码层面的基础优化到服务器配置的高级策略。通过具体实例分析,揭示如何有效减少页面加载时间、降低资源消耗,并提升用户体验。无论你是PHP新手还是资深开发者,都能在本文中找到实用的技巧和建议,助你打造更高效、更稳定的Web应用。 ####
|
10月前
|
人工智能 监控 物联网
数字孪生与智慧城市:构建未来城市模型
在信息化和智能化时代,数字孪生技术融合大数据、云计算、物联网和AI,成为推动智慧城市建设的关键力量。本文探讨其在城市规划、管理、交通、环保及公共服务中的应用,展现其如何优化城市运行,助力构建未来的理想城市模型。
|
10月前
|
机器学习/深度学习 弹性计算 编解码
阿里云服务器c7/c8a/c8y/c8i/g7/g8a/g8y/g8i/r7/r8a/r8y/r8i实例区别及选择参考
在阿里云目前的活动中,除了特价的轻量应用服务器和经济型e及通用算力型u1实例之外,属于计算型实例的实例有计算型c7/c8a/c8y/c8i,属于通用型实例的有通用型g7/g8a/g8y/g8i,属于内存型实例的有内存型r7/r8a/r8y/r8i。本文将详细介绍阿里云服务器中的c7、c8a、c8y、c8i、g7、g8a、g8y、g8i、r7、r8a、r8y、r8i等实例规格的性能、适用场景及选择参考,帮助用户更好地选择合适的云服务器实例。