blob: 1917e05e4941106c4b38abeb390a0607fab7c23d [file] [log] [blame]
Benjamin Peterson90f5ba52010-03-11 22:53:45 +00001#! /usr/bin/env python3
Guido van Rossumee60eb11998-08-12 17:47:52 +00002
3"""Reverse grep.
4
5Usage: rgrep [-i] pattern file
6"""
7
8import sys
9import re
Guido van Rossumee60eb11998-08-12 17:47:52 +000010import getopt
11
Florent Xiclunae4a33802010-08-09 12:24:20 +000012
Guido van Rossumee60eb11998-08-12 17:47:52 +000013def main():
Florent Xiclunae4a33802010-08-09 12:24:20 +000014 bufsize = 64 * 1024
Guido van Rossumee60eb11998-08-12 17:47:52 +000015 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)
Guido van Rossumb940e112007-01-10 16:19:56 +000027 except re.error as msg:
Florent Xiclunae4a33802010-08-09 12:24:20 +000028 usage("error in regular expression: %s" % msg)
Guido van Rossumee60eb11998-08-12 17:47:52 +000029 try:
30 f = open(filename)
Guido van Rossumb940e112007-01-10 16:19:56 +000031 except IOError as msg:
Florent Xiclunae4a33802010-08-09 12:24:20 +000032 usage("can't open %r: %s" % (filename, msg), 1)
Guido van Rossumee60eb11998-08-12 17:47:52 +000033 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)
Walter Dörwaldaaab30e2002-09-11 20:36:02 +000041 lines = buffer.split("\n")
Guido van Rossumee60eb11998-08-12 17:47:52 +000042 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
Florent Xiclunae4a33802010-08-09 12:24:20 +000053 for line in reversed(lines):
Guido van Rossumee60eb11998-08-12 17:47:52 +000054 if prog.search(line):
Collin Winter6afaeb72007-08-03 17:06:41 +000055 print(line)
Guido van Rossumee60eb11998-08-12 17:47:52 +000056
Florent Xiclunae4a33802010-08-09 12:24:20 +000057
Guido van Rossumee60eb11998-08-12 17:47:52 +000058def usage(msg, code=2):
59 sys.stdout = sys.stderr
Collin Winter6afaeb72007-08-03 17:06:41 +000060 print(msg)
61 print(__doc__)
Guido van Rossumee60eb11998-08-12 17:47:52 +000062 sys.exit(code)
63
Florent Xiclunae4a33802010-08-09 12:24:20 +000064
Guido van Rossumee60eb11998-08-12 17:47:52 +000065if __name__ == '__main__':
66 main()