| 
									
										
										
										
											2010-03-11 22:53:45 +00:00
										 |  |  | #! /usr/bin/env python3 | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | """Reverse grep.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Usage: rgrep [-i] pattern file | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import re | 
					
						
							|  |  |  | import getopt | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-09 12:24:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  | def main(): | 
					
						
							| 
									
										
										
										
											2010-08-09 12:24:20 +00:00
										 |  |  |     bufsize = 64 * 1024 | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  |     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) | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except re.error as msg: | 
					
						
							| 
									
										
										
										
											2010-08-09 12:24:20 +00:00
										 |  |  |         usage("error in regular expression: %s" % msg) | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  |     try: | 
					
						
							|  |  |  |         f = open(filename) | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except IOError as msg: | 
					
						
							| 
									
										
										
										
											2010-08-09 12:24:20 +00:00
										 |  |  |         usage("can't open %r: %s" % (filename, msg), 1) | 
					
						
							| 
									
										
										
										
											2019-03-30 08:33:02 +02:00
										 |  |  |     with f: | 
					
						
							|  |  |  |         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 = buffer.split("\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 | 
					
						
							|  |  |  |             for line in reversed(lines): | 
					
						
							|  |  |  |                 if prog.search(line): | 
					
						
							|  |  |  |                     print(line) | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-09 12:24:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  | def usage(msg, code=2): | 
					
						
							|  |  |  |     sys.stdout = sys.stderr | 
					
						
							| 
									
										
										
										
											2007-08-03 17:06:41 +00:00
										 |  |  |     print(msg) | 
					
						
							|  |  |  |     print(__doc__) | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  |     sys.exit(code) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-09 12:24:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-08-12 17:47:52 +00:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     main() |