diff options
author | Guido van Rossum <guido@python.org> | 1998-08-12 17:47:52 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1998-08-12 17:47:52 (GMT) |
commit | ee60eb127bc5665e49682264de9b123c3b28f8ba (patch) | |
tree | 163d073d401159f0c042faf605a064fb82a64660 /Tools/scripts/rgrep.py | |
parent | 697c1c7325769811f7bb4ab5242269af9636c7fd (diff) | |
download | cpython-ee60eb127bc5665e49682264de9b123c3b28f8ba.zip cpython-ee60eb127bc5665e49682264de9b123c3b28f8ba.tar.gz cpython-ee60eb127bc5665e49682264de9b123c3b28f8ba.tar.bz2 |
New tool: reverse grep (greps from the end). Uses a fairly efficient
strategy to read from the end of the file.
Diffstat (limited to 'Tools/scripts/rgrep.py')
-rwxr-xr-x | Tools/scripts/rgrep.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/Tools/scripts/rgrep.py b/Tools/scripts/rgrep.py new file mode 100755 index 0000000..0271242 --- /dev/null +++ b/Tools/scripts/rgrep.py @@ -0,0 +1,65 @@ +#! /usr/bin/env python + +"""Reverse grep. + +Usage: rgrep [-i] pattern file +""" + +import sys +import re +import string +import getopt + +def main(): + bufsize = 64*1024 + reflags = 0 + opts, args = getopt.getopt(sys.argv[1:], "i") + for o, a in opts: + if o == '-i': + reflags = reflags | re.IGNORECASE + if len(args) < 2: + usage("not enough arguments") + if len(args) > 2: + usage("exactly one file argument required") + pattern, filename = args + try: + prog = re.compile(pattern, reflags) + except re.error, msg: + usage("error in regular expression: %s" % str(msg)) + try: + f = open(filename) + except IOError, msg: + usage("can't open %s: %s" % (repr(filename), str(msg)), 1) + f.seek(0, 2) + pos = f.tell() + leftover = None + while pos > 0: + size = min(pos, bufsize) + pos = pos - size + f.seek(pos) + buffer = f.read(size) + lines = string.split(buffer, "\n") + del buffer + if leftover is None: + if not lines[-1]: + del lines[-1] + else: + lines[-1] = lines[-1] + leftover + if pos > 0: + leftover = lines[0] + del lines[0] + else: + leftover = None + lines.reverse() + for line in lines: + if prog.search(line): + print line + +def usage(msg, code=2): + sys.stdout = sys.stderr + print msg + print __doc__ + sys.exit(code) + +if __name__ == '__main__': + main() |