python合併兩個資料夾
阿新 • • 發佈:2018-11-06
# 作用: 7 # 合併並兩個目錄/資料夾。 8 # 將目錄A合併到目錄B,同級目錄下, 9 # 將A中有,B中沒有的目錄完全複製到B中; 10 # 將A中沒有,B中有的目錄不做改動; 11 # 將A中做了修改的檔案,在B的同級目錄下建立一個副本。(注意不是覆蓋) 12 # 13 # 適應場景: 14 # 一般A是從B複製過來的資料夾,做了修改後,想合併回B。 15 # 這樣在A中做的一些改動我們就不知道了,這個程式的作用是, 16 # 將A中修改的部分在B中更新。 17 # 18 # 版本: 19 # 將修改後的檔案完全複製過去 20 # 舊的檔案建立副本 21 # 基於檔案的MD5值判斷是否修改過 22 # 23 24 import os 25 import shutil 26 import time 27 import hashlib 28 import sys 29 30 def Help(): # 輸出幫助文件 31 print """ 32 PathMerge.py 33 作者:freecode 34 建立時間:2016.4.9 20:15 35 作用: 36 合併並兩個目錄/資料夾。 37 將目錄A合併到目錄B,同級目錄下, 38 將A中有,B中沒有的目錄完全複製到B中; 39 將A中沒有,B中有的目錄不做改動; 40 將A中做了修改的檔案,在B的同級目錄下建立一個副本。(注意不是覆蓋) 41 42 適應場景: 43 一般A是從B複製過來的資料夾,做了修改後,想合併回B。 44 這樣在A中做的一些改動我們就不知道了,這個程式的作用是, 45 將A中修改的部分在B中更新。 46 47 版本: 48 將修改後的檔案完全複製過去 49 舊的檔案建立副本 50 基於檔案的MD5值判斷是否修改過 51 """ 52 53 def GetFileMd5(filename): # 計算檔案的md5值 54 if not os.path.isfile(filename): 55 return 56 myhash = hashlib.md5() 57 f = file(filename,'rb') 58 while True: 59 b = f.read(8096) 60 if not b : 61 break 62 myhash.update(b) 63 f.close() 64 return myhash.hexdigest() 65 66 def isModify(A_file,B_file): # 判斷兩個檔案是否相同,如果不同,表示修改過 67 # 引數需是絕對路徑 68 return GetFileMd5(A_file) != GetFileMd5(B_file) 69 70 def Stamp2Time(Stamp): # 將時間戳轉換成時間顯示格式 71 timeArray = time.localtime(Stamp) 72 Time = time.strftime("%Y年%m月%d日 %H時%M分%S秒 舊檔案副本", timeArray) 73 return Time 74 75 def Merge(A_path,B_path): # 合併兩個目錄 76 B_paths = os.listdir(B_path) # 獲取當前B中的目錄結構 77 for fp in os.listdir(A_path): # 遍歷當前A目錄中的檔案或資料夾 78 A_new_path = os.path.join(A_path,fp) # A中的檔案或目錄 79 B_new_path = os.path.join(B_path,fp) # B中對應的檔案或路徑,不一定存在 80 81 if os.path.isdir(A_new_path): # A中的目錄 82 if os.path.exists(B_new_path): # 如果在B中存在 83 Merge(A_new_path,B_new_path) # 繼續合併下一級目錄 84 else: # 如果在B中不存在 85 print '[目錄]\t%s ===> %s' %(A_new_path,B_new_path) 86 shutil.copytree(A_new_path,B_new_path) # 完全複製目錄到B 87 88 elif os.path.isfile(A_new_path): # A中的檔案 89 if os.path.exists(B_new_path): # 如果在B中存在 90 s = os.stat(B_new_path) 91 if isModify(A_new_path,B_new_path) == True: # 如果該檔案修改過 92 # 建立副本 93 suffix = B_new_path.split('.')[-1] # 得到檔案的字尾名 94 # 將B中原檔案建立副本 95 B_copy_path = B_new_path[:-len(suffix)-1]+"(%s)."%(Stamp2Time(s.st_mtime))+suffix 96 print '[副本]\t%s ===> %s' %(A_new_path,B_copy_path) 97 shutil.copy2(B_new_path,B_copy_path) 98 # 將A中修改後檔案複製過來 99 print '[檔案]\t%s ===> %s' %(A_new_path,B_new_path) 100 shutil.copy2(A_new_path,B_new_path) 101 else: # 如果該檔案沒有修改過 102 pass # 不復制 103 104 else: # 如果在B中不存在 105 # 將該檔案複製過去 106 print '[檔案]\t%s ===> %s' %(A_new_path,B_new_path) 107 shutil.copy2(A_new_path,B_new_path) 108 109 # 執行模式 110 if __name__=='__main__': 111 print """ 112 歡迎使用PathMerge! 113 本程式將會把目錄A合併到目錄B,即 A ===> B 114 將A目錄中修改的內容在B目錄中更新 115 合併規則具體見 PathMerge.Help() 116 """ 117 if len(sys.argv) == 1: 118 path1 = raw_input('請輸入A目錄:').strip() 119 path2 = raw_input('請輸入B目錄:').strip() 120 elif len(sys.argv) == 2: 121 path1 = sys.argv[1].strip() 122 print 'A目錄為:%s\n' % (path1) 123 path2 = raw_input('請輸入B目錄:').strip() 124 elif len(sys.argv) == 3: 125 path1 = sys.argv[1].strip() 126 print 'A目錄為:%s\n' % (path1) 127 path2 = sys.argv[2].strip() 128 print 'B目錄為:%s\n' % (path2) 129 else: 130 print 'ERROR:引數錯誤!\n引數最多有三個!\n' 131 raw_input('\n請按回車鍵(Enter)退出……') 132 sys.exit(0) 133 # 去除目錄的引號 134 if path1[0]=='\"': 135 path1 = path1[1:-1] 136 if path2[0]=='\"': 137 path2 = path2[1:-1] 138 139 print """ 140 開始合併目錄 %s 141 到目錄 %s 142 %s ===> %s 143 """ %(path1,path2,path1,path2) 144 145 try: 146 print '合併中……' 147 Merge(path1,path2) 148 print '' 149 except Exception,e: 150 print '合併失敗!' 151 print '失敗原因:\n',e 152 else: 153 print '合併成功!' 154 155 raw_input('\n請按回車鍵(Enter)退出……') 156