#!/usr/bin/env python import os import re import shutil ################################################################################ # # # Script to batch rename files using a regular expression. # # # ################################################################################ def get_opt(): from optparse import OptionParser parser = OptionParser('usage: %prog -s(-c|-m) -i in_pattern -o out_pattern [-e regexp]') parser.add_option('-v', '--verbose', help='Verbose output.', action='store_true') parser.add_option('-t', '--test', help='Test mode.', action='store_true') parser.add_option('-c', '--copy', action='store_true', help='Use copy mode, which copies the FROM file into the ' \ 'TO name. Not compatible with the -m option.') parser.add_option('-m', '--move', action='store_true', help='Use move mode, which renameds the FROM to the ' \ 'TO file. Not compatible with the -c option.') parser.add_option('-i', '--inname', help='A regular expression to match against file names.') parser.add_option('-o', '--outname', help='A replacement pattern for output file name. ' \ 'The "To" pattern may refer capture groups in the "From" '\ 'parameter.') parser.add_option('-s', '--startdir', help='Recusively search the specified directory for files to process.') parser.add_option('-e', '--extra', help='An filter pattern to be applied on the full input file name, '\ 'only files that matches this pattern will be processed.') parser.defaults = { 'verbose' : False, 'test' : False, 'copy' : False, 'move' : False, 'inname' : None, 'outname' : None, 'startdir' : None, 'extra' : None } params, args = parser.parse_args() def _err(message): print message params.ok = False return params params.ok = True if not (params.copy or params.move): return _err('No mode specified: Please specify either -c (copy) or -m (move).') if (params.copy and params.move): return _err('Too many modes specified: Does not support -c (copy) AND ' \ '-m (move) together.') if not (params.inname and params.outname): return _err('File name required: Must specify a pattern for input and ' \ 'output files.') if not params.startdir: return _err('Must specify a starting directory.') params.inpattern = re.compile(params.inname) if params.extra: params.extrapattern = re.compile(params.extra) else: params.extrapattern = None return params class MatchedFile: def __init__(self): self.basename = None self.filename = None self.toname = None def __repr__(self): return 'b=%s, i=%s, o=%s' % (self.dirname, self.basename, self.toname) def match_file_or_dir(params, root): for elem in os.listdir(root): elem = os.path.join(root, elem) if os.path.isdir(elem): for subelem in match_file_or_dir(params, elem): yield subelem else: dirname = os.path.dirname(elem) basename = os.path.basename(elem) m = params.inpattern.match(basename) file = MatchedFile() file.basename = basename file.dirname = dirname if m: file.toname = m.expand(params.outname) if not params.extrapattern: yield file elif params.extrapattern.match(os.path.join(dirname, basename)): yield file if __name__ == '__main__': params = get_opt() if params.ok: for elem in match_file_or_dir(params, params.startdir): absname = os.path.join(elem.dirname, elem.basename) absto = os.path.join(elem.dirname, elem.toname) if elem.basename == elem.toname: print 'file %s not changed' % (absname) elif params.copy: if params.verbose: print 'cp %s %s' % (absname, absto) if not params.test: shutil.copyfile(absname, absto) elif params.move: if params.verbose: print 'mv %s %s' % (absname, absto) if not params.test: shutil.move(absname, absto)
Monday, July 12, 2010
pymv.py - A batch file rename script
Here's a script I wrote to batch rename files, tested on Python 2.5.2, support for "yield" keyword is required.
No comments:
Post a Comment