If the specified file exists, it is versioned by appending to the extension a three-digit number, starting with "000".
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 34 35 36
def VersionFile(file_spec, vtype='copy'): import os, shutil ok = 0 if os.path.isfile(file_spec): # or do other error checking... if vtype not in ('copy', 'rename'): vtype = 'copy' # determine root file name so the extension doesn't get longer and longer... n, e = os.path.splitext(file_spec) # is e an integer? try: num = int(e) root = n except ValueError: root = file_spec # find next available file version for i in xrange(1000): new_file = '%s.%03d' % (root, i) if not os.path.isfile(new_file): if vtype == 'copy': shutil.copy(file_spec, new_file) else: os.rename(file_spec, new_file) ok = 1 break return ok if __name__ == '__main__': # test code (you will need a file named test.txt) print VersionFile('test.txt') print VersionFile('test.txt') print VersionFile('test.txt')
It's polite to make backups of files before you mangle them. A standard way of doing so is to appending to the extension an incremented number. The optional second parameter allows you to specify whether the original file will be copied (the default) or renamed.
Limitation: after 1000 versions you're sunk. Better have an archive plan <grin>.
Bug. The code to detect and handle numeric extensions, namely the:
will not work because if the file name does have an extension, after the os.path.splitext() call the variable 'e' will contain a string that starts with a period.
Because of that fact, the int(e) expression will always raise an exception, in which case the entire file name will be assigned to varible 'root'. After this happens the renamed file would have another three-digit extension added to it each time this function is called.