• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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