任務:
你想對某個分類樹中的被修改過的檔案多次備份,以防止某次修改意外地抹去了你的編輯結果。 周期性的執行以下python指令碼可以對指定目錄下的檔案進行備份。
#-*- coding:utf-8 -*-import sys,os,shutil,filecmpMAXVERSIONS = 100def backup(tree_top, bakdir_name="bakdir"):for dir,subdirs,files in os.walk(tree_top):#確保每個目錄都有一個備份目錄backup_dir = os.path.join(dir,bakdir_name)if not os.path.exists(backup_dir):os.makedirs(backup_dir)#停止對備份目錄的遞迴subdirs[:] = [d for d in subdirs if d != bakdir_name]for file in files:filepath = os.path.join(dir,file)destpath = os.path.join(backup_dir,file)#檢查以前的版本是否存在for index in xrange(MAXVERSIONS):backfile = '%s.%2.2d' % (destpath, index)if not os.path.exists(backfile):breakif index > 0:old_backup = '%s.%2.2d' % (destpath,index-1)abspath = os.path.abspath(filepath)try:if os.path.isfile(old_backup) and filecmp.cmp(abspath, old_backup,shallow=False):continueexcept OSError:passtry:shutil.copy(filepath,backfile)except OSError:passif __name__ == '__main__':try:tree_top = sys.argv[1]except IndexError:tree_top = '.'backup(tree_top)
如果想針對某個特定尾碼名的檔案進行備份,(或對除去某個副檔名之外的檔案進行備份);在 for file in files 迴圈內加一個適當的測試即可:
for file in files: name,ext = os.path.splitext(file) if ext not in ('.py','.txt','.doc'): continue
注意以下代碼,避免os.walk遞迴到要備份的子目錄。當os.walk迭代開始之後,os.walk根據subdirs來進行子目錄迭代。這個關於os.walk的細節也是產生器應用的一個絕佳例子,它示範了產生器是如何通過迭代的代碼擷取資訊,同時又是如何反過來影響迭代。
subdirs[:] = [d for d in subdirs if d != bakdir_name]