環境:
html
Python 2.6.6python
linux系統linux
用到的模塊:filecmp正則表達式
filecmp提供了:單文件對比,多文件對比,目錄對比bash
單文件對比:採用filecmp.cmp(f1,f2[,shallow])方法,比較文件名爲f1和f2的文件的內容,相同返回True,不相同返回False,shallow默認是True,意思是隻根據os.stat()方法返回的文件基本信息進行對比,好比最後訪問時間、修改時間、狀態改變時間等,會忽略文件內容的對比。當shallow爲False時,則os.stat()與文件內容同時進行校驗。網絡
例子:app
>>> 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目錄給定的文件清單。該方法返回文件名的三個列表,分別爲匹配、不匹配、錯誤。匹配爲包含匹配的文件的列表,不匹配反之,錯誤列表包括了目錄不存在文件、不具有讀權限或其餘緣由致使的不能比較的文件清單。運維
例子:ide
先創建一些文件:函數
代碼:
>>> 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自動化運維技術與最佳實踐》-劉天斯 著