Task:
You want to back up the modified files in a certain directory tree multiple times to prevent a certain modification from accidentally erasing your editing results. Periodically execute the following python script to back up files in the specified directory.
#-*- coding:utf-8 -*- import sys,os,shutil,filecmp MAXVERSIONS = 100 def 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): break if 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): continue except OSError: pass try: shutil.copy(filepath,backfile) except OSError: pass if __name__ == '__main__': try: tree_top = sys.argv[1] except IndexError: tree_top = '.' backup(tree_top)
If you want to back up files with a specific suffix (or back up files except for a certain extension); just add an appropriate test in the for file in files loop:
for file in files: name,ext = os.path.splitext(file) if ext not in ('.py','.txt','.doc'): continue
Pay attention to the following code to avoid os.walk recursing into the subdirectory to be backed up. When os.walk iteration starts, os.walk iterates subdirectories based on subdirs. This detail about os.walk is also an excellent example of the use of generators, demonstrating how generators obtain information from iterative code and how they in turn affect the iteration.
subdirs[:] = [d for d in subdirs if d != bakdir_name]