1. 程式人生 > >python合併兩個資料夾

python合併兩個資料夾

# 作用:
  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