filecmp モジュールは、ファイルとフォルダーの内容を比較するために使用されます。これは軽量のツールであり、使い方は非常に簡単です。 Python 標準ライブラリには、ファイルの内容を比較するための difflib モジュールも提供されています。 difflib モジュールについては、次回その内訳を聞いてみましょう。
Filecmp は、ファイルとフォルダーを簡単に比較するための 2 つの関数を定義します:
filecmp.cmp(f1, f2[,shallow]):
2 つのファイルの内容が一致するかどうかを比較します。パラメータ f1 および f2 は、比較するファイルのパスを指定します。オプションのパラメータshallowは、ファイルを比較するときにファイル自体の属性を考慮する必要があるかどうかを指定します(ファイル属性はos.stat関数を通じて取得できます)。ファイルの内容が一致する場合、関数は True を返し、一致しない場合は False を返します。
filecmp.cmpfiles(dir1, dir2, common[,shallow]):
2 つのフォルダー内の指定されたファイルが等しいかどうかを比較します。パラメータ dir1 と dir2 は比較するフォルダを指定し、パラメータ common は比較するファイル名のリストを指定します。この関数は、一致、不一致、およびエラー ファイル リストをそれぞれ表す 3 つのリスト要素を含むタプルを返します。不正なファイルとは、存在しないファイル、またはファイルが読み取り不能であると判断されたか、ファイルを読み取る権限がない、またはその他の理由でファイルにアクセスできないことを指します。
filecmp モジュールは、フォルダーを比較するための dircmp クラスを定義します。このクラスを通じて 2 つのフォルダーを比較すると、詳細な比較結果 (フォルダー A にのみ存在するファイルのリストなど) を取得でき、サブファイルの再帰比較をサポートします。クリップの。
2.1 cmp簡単な使い方
使用法: filecmp.cmp (file1, file2)、file1とfile2が同じであればtrueを返します、それ以外の場合はtrueを返します。 、単一ファイルの差分比較と呼ばれる false が返されます。
2.1.1 コピーファイルを2回バックアップする
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 スクリプト出力を実行する
作成者アピール結果から、ファイルとファイルが比較されていることがわかりますOK。次に、vnc.conf.bakの内容を変更して、スクリプト
2.1.3を再度実行します
。1 # python lcmp.py vnc.conf vnc.conf.bak 2 Match success
match failed が出力され、 Ok の 2.2 cmpfiles
の簡単な使用法が証明されます。 pファイル(DIR1、DIR1、dir2、common[files...])、その機能は、dir1 ディレクトリと dir2 ディレクトリの違いを比較することです。このメソッドは、一致、不一致、エラーという 3 つのリストを返します。
2.2.1 ファイルをコピー
1 # sed -i s/vnc/liwang.org/ vnc.conf.bak2 # python lcmp.py vnc.conf vnc.conf.bak 3 Match failed
コードを書く1 # mkdir -p dir1 dir22 # cp lcmp.py vnc.conf vnc.conf.bak dir1/3 # cp lcmp.py vnc.conf dir2/
(ので入力を使用)
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])
可以看出,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.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 │ └── 789 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 789 is dirctory 6 //root/python/d_2_filecmp/dir2/789 is mkdirs 7 values : ///root/python/d_2_filecmp/dir1/4556/789 ///root/python/d_2_filecmp/dir2/4556/789 8 d is dirctory 9 //root/python/d_2_filecmp/dir2/d is mkdirs10 values : ////root/python/d_2_filecmp/dir1/4556/789/d ////root/python/d_2_filecmp/dir2/4556/789/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 │ └── 789 7 │ └── d 8 ├── lcmp.py 9 ├── vnc.conf10 └── vnc.conf.bak11 dir2/12 ├── 12313 │ └── 12345614 ├── 455615 │ └── 78916 │ └── d17 ├── lcmp.py18 ├── vnc.conf19 └── vnc.conf.bak20 21 8 directories, 8 files
由上,可知,备份完全成功,针对于定时执行python脚本,可以将脚本写入crontab中,开启定时任务即可。
以上がPython での filecmp の簡単な使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。