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