| #! /usr/bin/env python3 |
| |
| # Update a bunch of files according to a script. |
| # The input file contains lines of the form <filename>:<lineno>:<text>, |
| # meaning that the given line of the given file is to be replaced |
| # by the given text. This is useful for performing global substitutions |
| # on grep output: |
| |
| import os |
| import sys |
| import re |
| |
| pat = '^([^: \t\n]+):([1-9][0-9]*):' |
| prog = re.compile(pat) |
| |
| class FileObj: |
| def __init__(self, filename): |
| self.filename = filename |
| self.changed = 0 |
| try: |
| self.lines = open(filename, 'r').readlines() |
| except IOError as msg: |
| print('*** Can\'t open "%s":' % filename, msg) |
| self.lines = None |
| return |
| print('diffing', self.filename) |
| |
| def finish(self): |
| if not self.changed: |
| print('no changes to', self.filename) |
| return |
| try: |
| os.rename(self.filename, self.filename + '~') |
| fp = open(self.filename, 'w') |
| except (os.error, IOError) as msg: |
| print('*** Can\'t rewrite "%s":' % self.filename, msg) |
| return |
| print('writing', self.filename) |
| for line in self.lines: |
| fp.write(line) |
| fp.close() |
| self.changed = 0 |
| |
| def process(self, lineno, rest): |
| if self.lines is None: |
| print('(not processed): %s:%s:%s' % ( |
| self.filename, lineno, rest), end=' ') |
| return |
| i = eval(lineno) - 1 |
| if not 0 <= i < len(self.lines): |
| print('*** Line number out of range: %s:%s:%s' % ( |
| self.filename, lineno, rest), end=' ') |
| return |
| if self.lines[i] == rest: |
| print('(no change): %s:%s:%s' % ( |
| self.filename, lineno, rest), end=' ') |
| return |
| if not self.changed: |
| self.changed = 1 |
| print('%sc%s' % (lineno, lineno)) |
| print('<', self.lines[i], end=' ') |
| print('---') |
| self.lines[i] = rest |
| print('>', self.lines[i], end=' ') |
| |
| def main(): |
| if sys.argv[1:]: |
| try: |
| fp = open(sys.argv[1], 'r') |
| except IOError as msg: |
| print('Can\'t open "%s":' % sys.argv[1], msg) |
| sys.exit(1) |
| else: |
| fp = sys.stdin |
| curfile = None |
| while 1: |
| line = fp.readline() |
| if not line: |
| if curfile: curfile.finish() |
| break |
| n = prog.match(line) |
| if n < 0: |
| print('Funny line:', line, end=' ') |
| continue |
| filename, lineno = prog.group(1, 2) |
| if not curfile or filename != curfile.filename: |
| if curfile: curfile.finish() |
| curfile = FileObj(filename) |
| curfile.process(lineno, line[n:]) |
| |
| if __name__ == "__main__": |
| main() |