1. 程式人生 > >文件與目錄差異對比方法

文件與目錄差異對比方法

python

環境:

Python 2.6.6

linux系統


用到的模塊:filecmp

filecmp提供了:單文件對比,多文件對比,目錄對比


單文件對比:采用filecmp.cmp(f1,f2[,shallow])方法,比較文件名為f1和f2的文件的內容,相同返回True,不相同返回False,shallow默認是True,意思是只根據os.stat()方法返回的文件基本信息進行對比,比如最後訪問時間、修改時間、狀態改變時間等,會忽略文件內容的對比。當shallow為False時,則os.stat()與文件內容同時進行校驗。


例子:

>>> 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目錄給定的文件清單。該方法返回文件名的三個列表,分別為匹配、不匹配、錯誤。匹配為包含匹配的文件的列表,不匹配反之,錯誤列表包括了目錄不存在文件、不具備讀權限或其他原因導致的不能比較的文件清單。

例子:

先建立一些文件:

技術分享

代碼:

>>> 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都存在的子目錄、匹配的文件等,同時支持遞歸。


例子:

#!/usr/bin/env python
#-*—coding:utf-8-*-
#2017,9,7

import filecmp

a = "/root/dir1" #定義左目錄
b = "/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) #兩邊目錄中都存在,但是無法比較的文件

執行結果:

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:[]


實踐:效驗源與備份目錄差異

源代碼:

#!/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 x in only_in_one]
        [holderlist.append(os.path.abspath(os.path.join(dir1,x))) for x 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()

執行結果:

技術分享


總結\註意\拓展:


總結:

本次學習不僅學會了文件備份的效驗,而且學習到了一個語法:

 [holderlist.append(os.path.abspath(os.path.join(dir1,x))) for x in only_in_one]
 #正常寫法
 for x in only_in_one:
     holderlist.append(os.path.abspath(os.path.join(dir1,x)))

註意:

在寫程序的時候一定要註意縮進,不然容易報錯,我在寫下面這句的時候就老報語法錯誤,做後讓別人打一遍,我復制一下才成功:

return holderlist


拓展:

re.sub是re模塊重要的組成部分,並且功能也非常強大,主要功能實現正則的替換

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


解釋:

pattern:為表示正則中的模式字符串,
repl為replacement,被替換的內容,repl可以是字符串,也可以是函數。
string為正則表達式匹配的內容。
count:由於正則表達式匹配到的結果是多個,使用count來限定替換的個數(順序為從左向右),默認值為0,替換所有的匹配到的結果。
flag是匹配模式,可以使用按位或’|’表示同時生效,也可以在正則表達式字符串中指定。

例子:

>>>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自動化運維技術與最佳實踐》-劉天斯 著


技術分享

本文出自 “天道酬勤” 博客,謝絕轉載!

文件與目錄差異對比方法