Command line python script to get context lines on a search string

grep -B and -B flags don’t work when grep is used on the command line with readline support. So I created this little script that does work on the command line. use -h flag to learn. Here’s how I’ve used it:

1
ls -al | ./printcontext.py -b 1 -a 1 -d test.txt

This finds the test.txt file and prints the 2 files around it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/python
# print context when using a python script with readline support (command line piping)
# by inderpreetsingh.com
 
import sys, re
from optparse import OptionParser
 
def main():
    usage = "usage: %prog [options] needle"
    parser = OptionParser(usage)
    parser.add_option("-b", "--before", type="int", dest="before", default=0,
            help='Before context lines (a la grep)')
    parser.add_option("-a", "--after", type="int", dest="after", default=0,
            help='After context lines')
    parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False,
            help='Debug information.')
 
    #Not implemented
    #parser.add_option("-o", "--output", type="string", dest="output")
     
    (options, args) = parser.parse_args()
     
    if len(args) != 1:
        parser.error("Specify what you want to search")
     
    needle = args[0]
    if options.debug:
        print "\nNeedle: %s\nBefore context lines: %s\nAfter context lines: %s\n" % (needle, options.before, options.after)
     
 
    lines = sys.stdin.readlines()
    lines = [x.strip() for x in lines]
     
    lastline = ''
    i = 0
    for line in lines:
        if needle in line:
#        if re.search(needle, line):
            first = max(0, i - options.before)
            last = min(len(lines), i + options.after + 1)
             
            if options.debug:
                print "Found '%s' on line %d, printing line %d to %d" % (needle, i, first, last)
                 
            for println in lines[first:last]:
                print println
            print ""
        lastline = line
        i += 1
 
if __name__ == "__main__":
    main()