校驗源與備份目錄差異
阿新 • • 發佈:2018-12-31
一、概要
有時候我們無法確認備份目錄與原目錄是否保持一致,包括源目錄中的新檔案或目錄、更新檔案或目錄有無成功同步,定期進行校驗,沒有成功則希望有針對性地進行補備份。本示例使用了flilecmp模組的left_only、diff_files方法遞迴獲取源目錄的更新項,再通過shutil.copyfile、os.mkdirdirs方法對更新項進行復制,最終保持一致狀態。
二、示例
#!/usr/bin/env python 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: #遞迴子目錄 compareme(os.path.abspath(os.path.join(dir1,item)),os.path.abspath(os.path.join(dir2,item)))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: #重新呼叫compareme函式,重新遍歷新建立目錄的內容 destination_files=[] source_files=[] source_files=compareme(dir1,dir2) #呼叫compareme函式 for item in source_files: #獲取源目錄差異路徑清單,對應替換成備份目錄 destination_dir=re.sub(dir1,dir2,item) destination_files.append(destination_dir) print("update 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()
驗證:
測試中......