1#! /usr/bin/env python 2 3# Update a bunch of files according to a script. 4# The input file contains lines of the form <filename>:<lineno>:<text>, 5# meaning that the given line of the given file is to be replaced 6# by the given text. This is useful for performing global substitutions 7# on grep output: 8 9import os 10import sys 11import re 12 13pat = '^([^: \t\n]+):([1-9][0-9]*):' 14prog = re.compile(pat) 15 16class FileObj: 17 def __init__(self, filename): 18 self.filename = filename 19 self.changed = 0 20 try: 21 self.lines = open(filename, 'r').readlines() 22 except IOError, msg: 23 print '*** Can\'t open "%s":' % filename, msg 24 self.lines = None 25 return 26 print 'diffing', self.filename 27 28 def finish(self): 29 if not self.changed: 30 print 'no changes to', self.filename 31 return 32 try: 33 os.rename(self.filename, self.filename + '~') 34 fp = open(self.filename, 'w') 35 except (os.error, IOError), msg: 36 print '*** Can\'t rewrite "%s":' % self.filename, msg 37 return 38 print 'writing', self.filename 39 for line in self.lines: 40 fp.write(line) 41 fp.close() 42 self.changed = 0 43 44 def process(self, lineno, rest): 45 if self.lines is None: 46 print '(not processed): %s:%s:%s' % ( 47 self.filename, lineno, rest), 48 return 49 i = eval(lineno) - 1 50 if not 0 <= i < len(self.lines): 51 print '*** Line number out of range: %s:%s:%s' % ( 52 self.filename, lineno, rest), 53 return 54 if self.lines[i] == rest: 55 print '(no change): %s:%s:%s' % ( 56 self.filename, lineno, rest), 57 return 58 if not self.changed: 59 self.changed = 1 60 print '%sc%s' % (lineno, lineno) 61 print '<', self.lines[i], 62 print '---' 63 self.lines[i] = rest 64 print '>', self.lines[i], 65 66def main(): 67 if sys.argv[1:]: 68 try: 69 fp = open(sys.argv[1], 'r') 70 except IOError, msg: 71 print 'Can\'t open "%s":' % sys.argv[1], msg 72 sys.exit(1) 73 else: 74 fp = sys.stdin 75 curfile = None 76 while 1: 77 line = fp.readline() 78 if not line: 79 if curfile: curfile.finish() 80 break 81 n = prog.match(line) 82 if n < 0: 83 print 'Funny line:', line, 84 continue 85 filename, lineno = prog.group(1, 2) 86 if not curfile or filename <> curfile.filename: 87 if curfile: curfile.finish() 88 curfile = FileObj(filename) 89 curfile.process(lineno, line[n:]) 90 91if __name__ == "__main__": 92 main() 93