视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Python中filecmp的简单使用
2020-11-27 14:13:53 责编:小采
文档


filecmp模块用于比较文件及文件夹的内容,它是一个轻量级的工具,使用非常简单。python标准库还提供了difflib模块用于比较文件的内容。关于difflib模块,且听下回分解。

filecmp定义了两个函数,用于方便地比较文件与文件夹:

filecmp.cmp(f1, f2[, shallow]):

比较两个文件的内容是否匹配。参数f1, f2指定要比较的文件的路径。可选参数shallow指定比较文件时是否需要考虑文件本身的属性(通过os.stat函数可以获得文件属性)。如果文件内容匹配,函数返回True,否则返回False。

filecmp.cmpfiles(dir1, dir2, common[, shallow]):

比较两个文件夹内指定文件是否相等。参数dir1, dir2指定要比较的文件夹,参数common指定要比较的文件名列表。函数返回包含3个list元素的元组,分别表示匹配、不匹配以及错误的文件列表。错误的文件指的是不存在的文件,或文件被琐定不可读,或没权限读文件,或者由于其他原因访问不了该文件。

filecmp模块中定义了一个dircmp类,用于比较文件夹,通过该类比较两个文件夹,可以获取一些详细的比较结果(如只在A文件夹存在的文件列表),并支持子文件夹的递归比较。

2.filecmp的简单使用

2.1 cmp的简单使用

用法:filecmp.cmp(file1,file2),如果file1和file2相同的话,则会返回true,否则返回false,这就称为比较单文件的差异。

2.1.1 copy一个文件备份两次

1 # cp /etc/vnc.conf ./2 # cp /etc/vnc.conf ./vnc.conf.bak

2.1.2 编写python代码

 1 # cat lcmp.py 2 3 #!/usr/bin/env python 4 5 import sys 6 7 import filecmp 8 9 import os10 11 try:12 13 file1 = sys.argv[1]14 15 file2 = sys.argv[2]16 17 except:18 19 print ("Please follow the parameters")20 21 sys.exit()22 23 if os.path.isfile(file1) and os.path.isfile(file2) :24 25 if filecmp.cmp(file1,file2):26 27 print ("Match success")28 29 else :30 31 print ("Match failed")32 33 else:34 35 print ("Please check files")36 37 sys.exit()

2.1.2 执行脚本输出

1 # python lcmp.py vnc.conf vnc.conf.bak 
2 Match success

由上诉结果可以看出,文件是对比OK了的,现在修改vnc.conf.bak的内容,再执行脚本

2.1.3再次执行

1 # sed -i s/vnc/liwang.org/ vnc.conf.bak2 # python lcmp.py vnc.conf vnc.conf.bak 
3 Match failed

比对文件不成功,则输出了Match failed ,则证明脚本是ok的

2.2 cmpfiles的简单使用

用法:filecmp.cmpfiles(dir1,dir2,common[files...]),作用是对比dir1 和 dir2 目录的差异,该方法会返回三个list,分别是匹配,不匹配,错误。

2.2.1 复制文件

1 # mkdir -p dir1 dir22 # cp lcmp.py vnc.conf vnc.conf.bak dir1/3 # cp lcmp.py vnc.conf dir2/

2.2.2 编写python代码

 1 # cat lcmpfiles.py 2 3 #!/usr/bin/env python 4 5 import os 6 7 import filecmp 8 9 import sys10 11 dir1 = input("Please enter a folder to match:")12 13 dir2 = input("Please enter a folder to match:")14 15 files = []16 17 while True:18 19 local_files = input("Please enter the file to compare:[n/N Exit the input]")20 21 if local_files == 'N' or local_files == 'n':22 23 break24 25 elif local_files == '':26 27 continue28 29 else :30 31 files.append(local_files)32 33 try:34 35 os.path.exists(dir1)36 37 os.path.exists(dir2)38 39 except:40 41 print ("Pleae check the folder.")42 43 sys.exit()44 45 #print (filecmp.cmpfiles(dir1,dir2,files)[0])46 47 print ("It's file match:",filecmp.cmpfiles(dir1,dir2,files)[0])48 49 print ("The file does not match:",filecmp.cmpfiles(dir1,dir2,files)[1])50 51 print ("File does not exists:",filecmp.cmpfiles(dir1,dir2,files)[2])

2.2.3 用python3执行脚本(因为使用了input)

 1 # python3 lcmpfiles.py 
 2 Please enter a folder to match:dir1 3 Please enter a folder to match:dir2 4 Please enter the file to compare:[n/N Exit the input]lcmp.py 5 Please enter the file to compare:[n/N Exit the input]vnc.conf 6 Please enter the file to compare:[n/N Exit the input]vnc.conf.bak 7 Please enter the file to compare:[n/N Exit the input]n 8 It's file match: ['lcmp.py', 'vnc.conf'] 9 The file does not match: []10 File does not exists: ['vnc.conf.bak']

可以看出,lcmp.py 和 vnc.conf 在dir1 和dr2都有,且文件内容相同,而vnc.conf.bak在dir1有,dir没有,故输出,文件匹配:lcmp.py和vnc.conf ,文件不存在:vnc.conf.bak,文件不相同:无

2.2 dircmp的简单使用

语法:dircmp(a,b,[,ignore[,hide]]) 其中a,b是文件名,ignore是可以忽略的列表,hide代表隐藏列表,dircmp可以获得目录比较详细的信息,同时还支持递归。

dircmp提供了三个输出方法:

report() 比较当前指定目录中的内容

report_full_closure() 递归比较所有指定文件的内容

2.2.1 模拟环境

1 # ls dir1/ dir2/2 dir1/:3 hosts ld.so.conf sysconfig4 5 dir2/:6 hosts ld.so.conf sysconfig

其中,sysconfig 是一个目录 hosts 和 ld.so.conf都是文件,且hosts内容不一致 sysconfig中的文件也不一样

2.2.2 编写python代码

2.2.2.1 dircmp.report()

 1 # cat simple_filecmp.py 2 3 #!/usr/bin/env python 4 5 import filecmp 6 7 dir1 = "/root/python/d_2_filecmp/cmp/dir2" 8 9 dir2 = "/root/python/d_2_filecmp/cmp/dir1"10 11 dirobj = filecmp.dircmp(dir1,dir2)12 13 print (dirobj.report())

2.2.2.2 执行脚本

1 # python simple_filecmp.py 
2 diff /root/python/d_2_filecmp/cmp/dir2 /root/python/d_2_filecmp/cmp/dir13 Identical files : ['ld.so.conf']4 Differing files : ['hosts']5 Common subdirectories : ['sysconfig']6 None7 [root@localhost cmp]# cat simple_filecmp.py

由上面的结果,我们可以看出,report只能比对脚本的首层目录,而无法对子文件夹下的目录进行匹配

2.2.2.3 report_full_closure()

 1 # cat simple_filecmp_2.py 2 3 #!/usr/bin/env python 4 5 import filecmp 6 7 dir1 = "/root/python/d_2_filecmp/cmp/dir1/" 8 9 dir2 = "/root/python/d_2_filecmp/cmp/dir2/"10 11 dirobj = filecmp.dircmp(dir1,dir2)12 13 print (dirobj.report_full_closure())

2.2.2.4 执行脚本

1 diff /root/python/d_2_filecmp/cmp/dir1/ /root/python/d_2_filecmp/cmp/dir2/2 Identical files : ['ld.so.conf']3 Differing files : ['hosts']4 Common subdirectories : ['sysconfig']5 6 diff/root/python/d_2_filecmp/cmp/dir1/sysconfig /root/python/d_2_filecmp/cmp/dir2/sysconfig7 ......

由此可见差别report()和report_full_closure()的差别在于

3.filecmp案例

3.1 需求

需求:1.备份etc 文件夹下所有的内容,并且保持实时备份,如果有新的文件,则copy至备份文件中,如果有新的,则update之

3.2 流程图

3.2.1 初步流程图:

3.2.2 对比文件差异流程图

3.3 代码编写:

3.3.1 补充知识:

dircmp.left_only

只在左边出现的文件

 1 # cat simple_filecmp_3.py 2 3 #!/usr/bin/env python 4 5 import filecmp 6 7 dir1 = "/root/python/d_2_filecmp/cmp/dir1/" 8 9 dir2 = "/root/python/d_2_filecmp/cmp/dir2/"10 11 dirobj = filecmp.dircmp(dir1,dir2)12 13 print (dirobj.diff_files)

执行结果

1 # ls dir1 dir2/2 dir1:3 hosts ld.so.conf sysconfig teacher4 5 dir2/:6 hosts ld.so.conf sysconfig7 [root@localhost cmp]# python simple_filecmp_3.py 
8 ['teacher']

由上诉可见,当teacher只出现在dir1时,则会被抓取出来,所谓的left和right是相对于filecmp.dircmp而言的

dircmp.diff_files

返回不能匹配额文件

 1 # cat simple_filecmp_3.py 2 3 #!/usr/bin/env python 4 5 import filecmp 6 7 dir1 = "/root/python/d_2_filecmp/cmp/dir1/" 8 9 dir2 = "/root/python/d_2_filecmp/cmp/dir2/"10 11 dirobj = filecmp.dircmp(dir1,dir2)12 13 print (dirobj.diff_files)14 15 #print (dirobj.left_only)

执行结果

1 [root@localhost cmp]# ls dir1 dir22 dir1:3 hosts ld.so.conf sysconfig teacher4 5 dir2:6 hosts ld.so.conf sysconfig7 [root@localhost cmp]# python simple_filecmp_3.py 
8 ['hosts']9 [root@localhost cmp]#

之前我们修改过hosts的文件,文件内容已经不一致,现在已经被抓取出来了

3.3.2 编写自动备份脚本

 1 # cat d_7_12_filecmp.py 2 #!/usr/bin/env python 3 4 import filecmp 5 import os 6 import sys 7 import shutil 8 9 source_files = "/root/python/d_2_filecmp/dir1"10 target_files = "/root/python/d_2_filecmp/dir2"11 12 def check_common_dirs(source_files,target_files):13 dirsobj = filecmp.dircmp(source_files , target_files)14 15 common_dirs_list = dirsobj.common_dirs16 17 for common_line in common_dirs_list :18 files_contrast('/'+source_files+'/'+common_line,'/'+target_files+'/'+common_line)19 20 def files_contrast(dir1,dir2) :21 22 dirobj = filecmp.dircmp(dir1,dir2)23 24 no_exists_files = dirobj.left_only25 no_diff_files = dirobj.diff_files26 27 for exists_files in no_exists_files :28 29 if os.path.isfile(exists_files) :30 shutil.copyfile ('/'+dir1+'/'+exists_files , '/'+dir2+'/'+exists_files)31 else :32 print ("%s is dirctory" %(exists_files))33 os.makedirs('/'+dir2+'/'+exists_files)34 print ("%s is mkdirs" %('/'+target_files+'/'+exists_files))35 36 try :37 print ("values : %s %s" %('/'+dir1+'/'+exists_files , '/'+dir2+'/'+exists_files))38 files_contrast('/'+dir1+'/'+exists_files , '/'+dir2+'/'+exists_files)39 except :40 return 41 42 for diff_files in no_diff_files :43 if os.path.isfile(diff_files) :44 os.remove('/'+dir2+'/'+diff_files)45 shutil.copyfile ('/'+dir1+'/'+diff_files , '/'+dir2+'/'+diff_files)46 47 if os.path.exists(source_files) :48 49 if os.path.exists(target_files) == "False" :50 os.makedirs(target_files)51 52 files_contrast(source_files,target_files) 
53 check_common_dirs(source_files,target_files)54 55 else :56 print ("Soure files no exists")57 sys.exit()

3.4 执行脚本输出

3.4.1 查看文件

可知 dir2下没有任何文件

 1 # tree dir1/ dir2/ 2 dir1/ 3 ├── 123 4 │ └── 123456 5 ├── 4556 6 │ └── 7 7 │ └── d 8 ├── lcmp.py 9 ├── vnc.conf10 └── vnc.conf.bak11 dir2/12 13 3 directories, 5 files

3.4.2 执行脚本

 1 root@localhost d_2_filecmp]# python d_7_12_filecmp.py 
 2 4556 is dirctory 3 //root/python/d_2_filecmp/dir2/4556 is mkdirs 4 values : //root/python/d_2_filecmp/dir1/4556 //root/python/d_2_filecmp/dir2/4556 5 7 is dirctory 6 //root/python/d_2_filecmp/dir2/7 is mkdirs 7 values : ///root/python/d_2_filecmp/dir1/4556/7 ///root/python/d_2_filecmp/dir2/4556/7 8 d is dirctory 9 //root/python/d_2_filecmp/dir2/d is mkdirs10 values : ////root/python/d_2_filecmp/dir1/4556/7/d ////root/python/d_2_filecmp/dir2/4556/7/d11 123 is dirctory12 //root/python/d_2_filecmp/dir2/123 is mkdirs13 values : //root/python/d_2_filecmp/dir1/123 //root/python/d_2_filecmp/dir2/12314 123456 is dirctory15 //root/python/d_2_filecmp/dir2/123456 is mkdirs16 values : ///root/python/d_2_filecmp/dir1/123/123456 ///root/python/d_2_filecmp/dir2/123/123456

可以看出,备份的信息,前面的多个/可以不必理会,linux只识别一个/

3.4.3 查看备份效果

 1 # tree dir1/ dir2/ 2 dir1/ 3 ├── 123 4 │ └── 123456 5 ├── 4556 6 │ └── 7 7 │ └── d 8 ├── lcmp.py 9 ├── vnc.conf10 └── vnc.conf.bak11 dir2/12 ├── 12313 │ └── 12345614 ├── 455615 │ └── 716 │ └── d17 ├── lcmp.py18 ├── vnc.conf19 └── vnc.conf.bak20 21 8 directories, 8 files

由上,可知,备份完全成功,针对于定时执行python脚本,可以将脚本写入crontab中,开启定时任务即可。

下载本文
显示全文
专题