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 f.seek(0, 2) 34 pos = f.tell() 35 leftover = None 36 while pos > 0: 37 size = min(pos, bufsize) 38 pos = pos - size 39 f.seek(pos) 40 buffer = f.read(size) 41 lines = buffer.split("\n") 42 del buffer 43 if leftover is None: 44 if not lines[-1]: 45 del lines[-1] 46 else: 47 lines[-1] = lines[-1] + leftover 48 if pos > 0: 49 leftover = lines[0] 50 del lines[0] 51 else: 52 leftover = None 53 for line in reversed(lines): 54 if prog.search(line): 55 print(line) 56 57 58def usage(msg, code=2): 59 sys.stdout = sys.stderr 60 print(msg) 61 print(__doc__) 62 sys.exit(code) 63 64 65if __name__ == '__main__': 66 main() 67