Welcome, guest | Sign In | My Account | Store | Cart
Python, 33 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def backupSave(fileName, prefix='', suffix='bk', count=5):
     ''' backupSave: backup a file to up to number of versions defined by count.
    
     Let fileName = 'c:/tmp/myfile.txt'
         prefix   = 'x_'
         suffix   = 'BAK'
         count    = 5 
    
     This function will check if 
    
        x_myfile.txt.BAKi

    exists in the same folder, where 1<=i<=count
    
    If found, save it to x_myfile.txt.BAKi+1
    
     version: 04b43
     module : panTools    
     author : Runsun Pan
     '''
     import os, shutil
     folder, fileName = os.path.split(fileName)
     if not folder.strip(): folder = '.'
     files = os.listdir(folder)
     
     for i in range(count):
        j = count-i-1
        fn  = prefix + fileName  + '.' + suffix + str(j)
        if j == 0: fn = fileName
        nfn = prefix + fileName +  '.' + suffix + str(j+1)
        fn = os.path.join(folder, fn)
        if os.path.exists(fn):
           shutil.copy(fn, nfn) 

backupSave('myfile.txt') ===> will copy myfile.txt to myfile.txt.bk1

run it the 2nd time ==> will copy myfile.txt.bk1 to myfile.txt.bk2 and copy myfile.txt to myfile.txt.bk1

run it the 3rd time ==> copy myfile.txt.bk2 to myfile.txt.bk3 copy myfile.txt.bk1 to myfile.txt.bk2 and copy myfile.txt to myfile.txt.bk1 ... up to a number of versions defined by the argument 'count'

2 comments

Denis Barmenkov 19 years, 4 months ago  # | flag

my version may be cleaner ;). Hi,

with os function wrappers this task will be more pleasant, especially for smart file handling (gaps in BAK filenames) and using rename instead of copy.

def rename_to_backup(fn, backup_amount=5, backup_ext='BAK'):

   
import os.path, os

   
def bak_name(i):
       
if i &lt; 1: return fn
       
return '%s.%s%d' % (fn, backup_ext, i)
   
def exists(i):
        f
= bak_name(i)
       
return os.path.exists(f)
   
def unlink(i):
        f
= bak_name(i)
       
try: os.unlink(f)
       
except IOError: pass
   
def rename(i, j):
       
fi = bak_name(i)
        fj
= bak_name(j)
       
try: os.rename(fi, fj)
       
except IOError: pass

   
for i in range(backup_amount - 1, -1, -1):
       
if exists(i):
           
if exists(i-1):
               
if exists(i+1): unlink(i+1)
                rename
(i, i+1)
Denis Barmenkov 19 years, 2 months ago  # | flag

And smarter... this version doesnt allow 'gaps' between backup file names, and not perform extra file renames:

def rename_to_backup(fn, backup_amount=5, backup_ext='BAK'):

   
import os.path, os

   
def bak_name(i):
       
if i &lt; 1: return fn
       
return '%s.%s%d' % (fn, backup_ext, i)
   
def exists(i):
        f
= bak_name(i)
       
return os.path.exists(f)
   
def unlink(i):
       
if not exists(i): return
        f
= bak_name(i)
       
try:
           
print 'bpc.file> delete %s' % (f)
            os
.unlink(f)
       
except IOError, OSError:
           
pass
   
def rename(i, j):
       
fi = bak_name(i)
        fj
= bak_name(j)
       
try:
           
print 'bpc.file> rename %s => %s' % (fi, fj)
            os
.rename(fi, fj)
       
except IOError:
           
pass

   
def rename_one(index):
       
print 'rename_one> index=%d' % index
       
if index == backup_amount:
           
print 'rename_one> Last Index'
            unlink
(index)
       
else:
           
if exists(index):
               
print 'rename_one>   next index: %d'  % index
                rename_one
(index + 1)
                rename
(index, index + 1)

    rename_one
(0)