1#! /usr/bin/env python3 2 3"""Reverse grep. 4 5Usage: rgrep [-i] pattern file 6""" 7 8import sys 9import re 10import getopt 11 12 13def main(): 14 bufsize = 64 * 1024 15 reflags = 0 16 opts, args = getopt.getopt(sys.argv[1:], "i") 17 for o, a in opts: 18 if o == '-i': 19 reflags = reflags | re.IGNORECASE 20 if len(args) < 2: 21 usage("not enough arguments") 22 if len(args) > 2: 23 usage("exactly one file argument required") 24 pattern, filename = args 25 try: 26 prog = re.compile(pattern, reflags) 27 except re.error as msg: 28 usage("error in regular expression: %s" % msg) 29 try: 30 f = open(filename) 31 except IOError as msg: 32 usage("can't open %r: %s" % (filename, msg), 1) 33 with f: 34 f.seek(0, 2) 35 pos = f.tell() 36 leftover = None 37 while pos > 0: 38 size = min(pos, bufsize) 39 pos = pos - size 40 f.seek(pos) 41 buffer = f.read(size) 42 lines = buffer.split("\n") 43 del buffer 44 if leftover is None: 45 if not lines[-1]: 46 del lines[-1] 47 else: 48 lines[-1] = lines[-1] + leftover 49 if pos > 0: 50 leftover = lines[0] 51 del lines[0] 52 else: 53 leftover = None 54 for line in reversed(lines): 55 if prog.search(line): 56 print(line) 57 58 59def usage(msg, code=2): 60 sys.stdout = sys.stderr 61 print(msg) 62 print(__doc__) 63 sys.exit(code) 64 65 66if __name__ == '__main__': 67 main() 68