summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-08-12 17:47:52 (GMT)
committerGuido van Rossum <guido@python.org>1998-08-12 17:47:52 (GMT)
commitee60eb127bc5665e49682264de9b123c3b28f8ba (patch)
tree163d073d401159f0c042faf605a064fb82a64660 /Tools
parent697c1c7325769811f7bb4ab5242269af9636c7fd (diff)
downloadcpython-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')
-rwxr-xr-xTools/scripts/rgrep.py65
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()