Mercurial > dotfiles
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:c30d68fbd368 | 1:91dbdbea15e5 |
---|---|
1 #!/usr/bin/env python | |
2 | |
3 from itertools import imap as map | |
4 from itertools import izip as zip | |
5 | |
6 import re | |
7 whitespace_chars = { | |
8 '\a': r'\a', | |
9 '\b': r'\b', | |
10 '\t': r'\t', | |
11 '\n': r'\n', | |
12 '\v': r'\v', | |
13 '\f': r'\f', | |
14 '\r': r'\r', | |
15 } | |
16 whitespace_chars_exp = re.compile('[' + ''.join(whitespace_chars) + ']') | |
17 chars_to_escape = dict(zip(map(chr, xrange(0x00, 0x20)), ('\\' + ch for ch in map(chr, xrange(0x00, 0x20))))) | |
18 for ch in '{}' "'" '"' '$*?': | |
19 chars_to_escape[ch] = '\\' + ch | |
20 for ch in whitespace_chars: | |
21 del chars_to_escape[ch] # Let whitespace_chars handle these. | |
22 chars_to_escape_exp = re.compile('[][\\' + ''.join(chars_to_escape) + ']') | |
23 chars_to_escape['['] = '\[' | |
24 chars_to_escape[']'] = '\]' | |
25 chars_to_escape['\\'] = '\\\\' | |
26 minimal_chars_to_escape_exp = re.compile("[\\']") | |
27 | |
28 def quote_argument(arg): | |
29 count = 0 | |
30 match = chars_to_escape_exp.search(arg) | |
31 while match: | |
32 count += 1 | |
33 match = chars_to_escape_exp.search(arg, match.end()) | |
34 else: | |
35 del match | |
36 | |
37 if count > 2: | |
38 arg = "'" + re.sub(minimal_chars_to_escape_exp, lambda match: '\\' + match.group(0), arg) + "'" | |
39 else: | |
40 arg = re.sub(chars_to_escape_exp, lambda match: chars_to_escape[match.group(0)], arg) | |
41 | |
42 arg = re.sub(whitespace_chars_exp, lambda match: whitespace_chars[match.group(0)], arg) | |
43 return arg | |
44 | |
45 def custom_rename(option, opt_str, value, parser): | |
46 for i, arg in enumerate(parser.rargs): | |
47 if arg == ';': | |
48 break | |
49 parser.values.ensure_value('custom_rename', parser.rargs[:i]) | |
50 del parser.rargs[:i + 1] | |
51 | |
52 import optparse | |
53 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.") | |
54 parser.add_option('-e', '--program', action='append', default=['']) | |
55 parser.add_option('--vcs', metavar='VCS', help='Version-control system with which to rename files, using <VCS> mv <SRC> <DST>; overridden by --custom-rename') | |
56 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) | |
57 parser.add_option('-q', '--quiet', action='store_true', default=False) | |
58 opts, args = parser.parse_args() | |
59 | |
60 try: | |
61 custom_rename = opts.custom_rename | |
62 except AttributeError: | |
63 try: | |
64 custom_rename = [opts.vcs, 'mv'] | |
65 except AttributeError: | |
66 custom_rename = None | |
67 | |
68 def prefix_with_dash_e(seq): | |
69 for arg in seq: | |
70 yield '-e' | |
71 yield arg | |
72 | |
73 import subprocess | |
74 sed = subprocess.Popen(['sed', '-El'] + list(prefix_with_dash_e(opts.program)), stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |
75 | |
76 import os, sys | |
77 for src in args: | |
78 sed.stdin.write(src + '\n') | |
79 sed.stdin.flush() | |
80 dst = sed.stdout.readline().rstrip('\n') | |
81 if src == dst: | |
82 if not opts.quiet: | |
83 print >>sys.stderr, 'sed program did not transform %r - skipping' % (src,) | |
84 else: | |
85 if custom_rename: | |
86 src_and_dst = [src, dst] | |
87 rename_cmd = list(custom_rename) | |
88 for i, arg in enumerate(rename_cmd): | |
89 if arg == '{SRC}': | |
90 rename_cmd[i] = src | |
91 elif arg == '{DST}': | |
92 rename_cmd[i] = dst | |
93 elif arg == '{}': | |
94 try: | |
95 rename_cmd[i] = src_and_dst.pop(0) | |
96 except IndexError: | |
97 sys.exit('Too many {} arguments in custom rename command %r' % (custom_rename,)) | |
98 else: | |
99 rename_cmd += src_and_dst | |
100 | |
101 if not opts.quiet: | |
102 print >>sys.stderr, ' '.join(map(quote_argument, rename_cmd)) | |
103 subprocess.check_call(rename_cmd) | |
104 else: | |
105 if not opts.quiet: | |
106 print >>sys.stderr, 'Renaming %r to %r' % (src, dst) | |
107 os.rename(src, dst) | |
108 | |
109 sed.stdin.close() | |
110 sys.exit(sed.wait()) |