Mercurial > dotfiles
diff unixSoft/bin/sednames.py @ 1:91dbdbea15e5
Merge in uncommitted changes.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Wed, 26 Nov 2008 15:03:40 -0600 |
parents | |
children |
line wrap: on
line diff
new file mode 100755 --- /dev/null +++ b/unixSoft/bin/sednames.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python + +from itertools import imap as map +from itertools import izip as zip + +import re +whitespace_chars = { + '\a': r'\a', + '\b': r'\b', + '\t': r'\t', + '\n': r'\n', + '\v': r'\v', + '\f': r'\f', + '\r': r'\r', +} +whitespace_chars_exp = re.compile('[' + ''.join(whitespace_chars) + ']') +chars_to_escape = dict(zip(map(chr, xrange(0x00, 0x20)), ('\\' + ch for ch in map(chr, xrange(0x00, 0x20))))) +for ch in '{}' "'" '"' '$*?': + chars_to_escape[ch] = '\\' + ch +for ch in whitespace_chars: + del chars_to_escape[ch] # Let whitespace_chars handle these. +chars_to_escape_exp = re.compile('[][\\' + ''.join(chars_to_escape) + ']') +chars_to_escape['['] = '\[' +chars_to_escape[']'] = '\]' +chars_to_escape['\\'] = '\\\\' +minimal_chars_to_escape_exp = re.compile("[\\']") + +def quote_argument(arg): + count = 0 + match = chars_to_escape_exp.search(arg) + while match: + count += 1 + match = chars_to_escape_exp.search(arg, match.end()) + else: + del match + + if count > 2: + arg = "'" + re.sub(minimal_chars_to_escape_exp, lambda match: '\\' + match.group(0), arg) + "'" + else: + arg = re.sub(chars_to_escape_exp, lambda match: chars_to_escape[match.group(0)], arg) + + arg = re.sub(whitespace_chars_exp, lambda match: whitespace_chars[match.group(0)], arg) + return arg + +def custom_rename(option, opt_str, value, parser): + for i, arg in enumerate(parser.rargs): + if arg == ';': + break + parser.values.ensure_value('custom_rename', parser.rargs[:i]) + del parser.rargs[:i + 1] + +import optparse +parser = optparse.OptionParser(description="This program batch-renames files, optionally using a VCS (such as svn, hg, or bzr) or other external program to do the renaming. You specify the rename operations using sed commands, which you specify using the -e option.") +parser.add_option('-e', '--program', action='append', default=['']) +parser.add_option('--vcs', metavar='VCS', help='Version-control system with which to rename files, using <VCS> mv <SRC> <DST>; overridden by --custom-rename') +parser.add_option('--custom-rename', help='Custom command to rename the file (e.g., hg mv); works like find(1) -exec (but with two {}, which are src and dst in that order), or you can use {SRC} and {DST}, or you can omit {...} entirely in which case src and dst will be appended in that order', action='callback', type=None, callback=custom_rename, default=None) +parser.add_option('-q', '--quiet', action='store_true', default=False) +opts, args = parser.parse_args() + +try: + custom_rename = opts.custom_rename +except AttributeError: + try: + custom_rename = [opts.vcs, 'mv'] + except AttributeError: + custom_rename = None + +def prefix_with_dash_e(seq): + for arg in seq: + yield '-e' + yield arg + +import subprocess +sed = subprocess.Popen(['sed', '-El'] + list(prefix_with_dash_e(opts.program)), stdin=subprocess.PIPE, stdout=subprocess.PIPE) + +import os, sys +for src in args: + sed.stdin.write(src + '\n') + sed.stdin.flush() + dst = sed.stdout.readline().rstrip('\n') + if src == dst: + if not opts.quiet: + print >>sys.stderr, 'sed program did not transform %r - skipping' % (src,) + else: + if custom_rename: + src_and_dst = [src, dst] + rename_cmd = list(custom_rename) + for i, arg in enumerate(rename_cmd): + if arg == '{SRC}': + rename_cmd[i] = src + elif arg == '{DST}': + rename_cmd[i] = dst + elif arg == '{}': + try: + rename_cmd[i] = src_and_dst.pop(0) + except IndexError: + sys.exit('Too many {} arguments in custom rename command %r' % (custom_rename,)) + else: + rename_cmd += src_and_dst + + if not opts.quiet: + print >>sys.stderr, ' '.join(map(quote_argument, rename_cmd)) + subprocess.check_call(rename_cmd) + else: + if not opts.quiet: + print >>sys.stderr, 'Renaming %r to %r' % (src, dst) + os.rename(src, dst) + +sed.stdin.close() +sys.exit(sed.wait())