#!/usr/bin/env python3
# -*- coding: utf8 -*-
"""
Usage:
exgrep [options] (-f PATTERN_FILE | TERM) (EXCEL_FILE... | --read-from INFILE)

Options:
TERM                The term to grep for. Can be any valid (python) regular expression.
EXCEL_FILE          The list of files to search through
-c COL              Only search in the column specified by COL (either a 1-based number or a letter)
-r ROW              Only search in the row specified by ROW
-o                  Only output the matched part
-i                  Perform a case-insensitive match
-f PATTERN_FILE     A newline separated file containing one pattern per line
--read-from INFILE  A newline separated file containing the path to one Excel file to search per line
"""
import os
import re
import string

from docopt import docopt
import signal
import sys
import xlrd

__author__ = 'peter'


def main():
    args = docopt(__doc__)

    signal.signal(signal.SIGINT, lambda x, y: sys.exit(130))

    args = parse_args(args)
    flags = re.UNICODE
    if args['-i']:
        flags |= re.IGNORECASE

    if args['-f']:
        ps = [re.compile(x.strip(), flags) for x in open(args['-f'])]
    else:
        ps = [args['TERM']]

    if args['--read-from']:
        args['EXCEL_FILE'] = [x.strip() for x in open(args['--read-from'])]

    for f in args['EXCEL_FILE']:
        workbook = xlrd.open_workbook(f)
        sheet = workbook.sheet_by_index(0)

        if args['-r']:
            check_row(args, f, ps, sheet, int(args['-r']))
            continue

        for rownum in range(sheet.nrows):
            check_row(args, f, ps, sheet, rownum)


def parse_args(args):
    if args['-c']:
        try:
            int(args['-c'])
            args['-c'] -= 1  # fixed 1-based
        except ValueError:
            args['-c'] = string.ascii_lowercase.index(args['-c'].lower())
    return args


def check_row(args, f, ps, sheet, rownum):
    """
    Check a row for the presence of pattern p.
    """
    for idx, v in enumerate(sheet.row_values(rownum)):
        if args['-c'] and idx != int(args['-c']):
            continue
        for p in ps:
            s = p.search(str(v))
            if s:
                to_print = ''
                if len(ps) > 1:
                    to_print += '"{0}":'.format(p.pattern)
                if len(args['EXCEL_FILE']) > 1:
                    to_print += os.path.basename(f)
                to_print += ':{0}: '.format(rownum + 1)
                if args['-o']:
                    to_print += str(s.group(0))
                else:
                    to_print += str(sheet.row_values(rownum))
                print(to_print)


if __name__ == '__main__':
    main()
@@ -826,16 +826,28 @@
 ort xlrd
+%0Aimport util
 %0A%0A__auth
@@ -1329,24 +1329,63 @@
 CEL_FILE'%5D:%0A
+        if args%5B'-r'%5D is not None:%0A    
         work
@@ -1421,16 +1421,20 @@
         
+   
+ 
 sheet = 
@@ -1463,32 +1463,8 @@
 x(0)
-%0A%0A        if args%5B'-r'%5D:
 %0A   
@@ -1499,18 +1499,36 @@
 ps, 
-sheet, int
+args%5B'-r'%5D, sheet.row_values
 (arg
@@ -1558,25 +1558,39 @@
 ontinue%0A
-%0A
+        else:%0A 
         
 for rown
@@ -1585,42 +1585,51 @@
     
+   
 for 
-rownum in range(sheet.n
+idx, row in util.yield_
 rows
+(f
 ):%0A
+    
     
@@ -1659,29 +1659,24 @@
  f, ps, 
-sheet
+idx
 , row
-num
 )%0A%0A%0Adef 
@@ -1710,16 +1710,28 @@
 gs%5B'-c'%5D
+ is not None
 :%0A      
@@ -1748,16 +1748,29 @@
         
+ args%5B'-c'%5D =
  int(arg
@@ -1924,16 +1924,258 @@
 ower())%0A
+%0A    if args%5B'-r'%5D is not None:%0A        try:%0A            args%5B'-r'%5D = int(args%5B'-r'%5D)%0A            args%5B'-r'%5D -= 1  # fixed 1-based%0A        except ValueError:%0A            print('-r argument must be a valid integer!')%0A            sys.exit(-1)%0A%0A
     retu
@@ -2215,21 +2215,16 @@
 ps, 
-sheet
+idx
 , row
-num
 ):%0A 
@@ -2317,32 +2317,11 @@
 ate(
-sheet.row_values(rownum)
+row
 ):%0A 
@@ -2880,32 +2880,9 @@
 str(
-sheet.row_values(rownum)
+v
 )%0A  

Use util.yield_rows instead of separate code