#!/usr/bin/python # ngrep: new way of grepping stuff # #Copyright (C) 2007 Thiago Galesi # #This program is free software; you can redistribute it and/or #modify it under the terms of the GNU General Public License #as published by the Free Software Foundation; either version 2 #of the License, or (at your option) any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # import sys, re, getopt, fileinput, os, stat, linecache # substituto para a o grep # features # comportamento do egrep, porque regex velhas SUX # novas opissoes def usage(): print """ nwgrep: A new option for grepping stuff v 0.1 options: -r recurse subdirectories (works) -f files to grep (works) -v prints line number for vi opening -e regex to look for -frgx regex to determine which files to print -n prints line number information -s simplified file name printing: file.txt instead of... /somewhere/over/the/rainbow/file.txt -w does not print file name at beginning of path -y does not print spaces/tabs before the line but instead once before any matching lines """ sys.exit(2) def walktree(top, recurse): #print top file_list = [] islist = False for f in top: try: mode = os.stat(f)[stat.ST_MODE] except: continue if stat.S_ISDIR(mode): # It's a directory, recurse into it #print str(f)+'is a directory' if not stat.S_ISLNK(mode): # not going round the tail if (recurse==True): lstd = os.listdir(f) fls = [] for i in lstd: fls.append(os.path.join(f, i)) file_list += walktree(fls, True) elif stat.S_ISREG(mode): file_list.append(f) return file_list def spath(nrm): vl = nrm.rfind('/') if vl!=(-1): return nrm[vl+1:] def intr_line_asm(file_list, comp_regx): ill = [] for nmf in file_list: fname = nmf try: for line in fileinput.input(nmf): if (comp_regx.search(line)!=None): ill.append((fname, fileinput.filelineno(), line[:-1])) except IOError: sys.stderr.write("Error opening file %s \n"%(nmf)) except KeyboardInterrupt: sys.exit(1) except: sys.stderr.write("This should not have happened") return ill # list of opts # lnn - prints line number # shp - prints short path # vi - prints path + line number in vi copy paste format # jof - prints file name just once def il_print(ill, opt_l): lineno = False shp = False jof = False vio = False sks = False if 'lnn' in opt_l: lineno = True if 'shp' in opt_l: shp = True if 'jof' in opt_l: jof = True if 'vi' in opt_l: vio = True if 'sks' in opt_l: sks = True lfn = "/" for le in ill: linenotxt = "" prld = "" if (lineno): if (vio): linenotxt += " +%d "%(le[1]) else: linenotxt += ":%d "%(le[1]) if (jof): if (le[0] != lfn): lfn = le[0] if (shp): print "<%s>"%(spath(lfn)) else: print "<%s>"%(lfn) else: if (shp): prld += spath(le[0]) else: prld += le[0] ltxt = le[2] if (sks): ltxt = ltxt.lstrip() prld += linenotxt print "%s %s"%(prld, ltxt) def tk2frgx(opt): lox = dict() lox['cf'] = '\.((c((pp)|c)?)|(h(h)?))$' lox['ch'] = '\.(h(h)?)$' lox['cs'] = '\.((c((pp)|c)))?$' lox['py'] = '\.py$' try: rt = lox[opt] except: print 'Invalid regex set choice\n' sys.exit(5) return rt def main(): #print sys.argv[1:] try: opcs, args = getopt.gnu_getopt(sys.argv[1:], 'rf:e:c:nswvy',['frgx=', 'short_path', 'fx=']) except getopt.GetoptError: usage() #print opcs o_recurse = False o_lineno = False o_regex = '' o_files = '' o_contxt = '' o_frgx = '' o_nwfi = False o_shortpath = False fpol = [] for op, vl in opcs: if op in ['-s','--short_path']: o_shortpath = True fpol.append('shp') if op == '-r': o_recurse = True if op == '-f': o_files = vl if op == '-e': o_regex = vl if op == '-w': o_nwfi = True fpol.append('jof') if op == '-v': fpol.append('vi') fpol.append('lnn') o_lineno = True if op == '-y': fpol.append('sks') if op == '-c': o_contxt = vl if op == '--frgx': o_frgx = vl if op == '-n': o_lineno = True fpol.append('lnn') if op == '--fx': o_frgx = tk2frgx(vl) if (o_regex==''): usage() #if ((o_files=='') & (len(args)==0)): usage() try: crgx = re.compile(o_regex) except: print 'faulty regular expression' sys.exit(3) #print o_files if (type(o_files)==str): o_files = [o_files] o_files += args if (o_recurse == False): o_files = walktree(o_files, False) else: o_files = walktree(o_files, True) if (len(o_files)==0): sys.exit(0) if (o_frgx!=''): try: frgx = re.compile(o_frgx) except: print 'faulty file regular expression' sys.exit(3) oof = [] for fl in o_files: if (frgx.search(fl)!=None): oof.append(fl) o_files = oof #print 'oof = ' +str(oof) #comp_grep(o_files, crgx, o_contxt, o_nwfi, o_shortpath, o_lineno) for fl in o_files: ill = intr_line_asm([fl], crgx) if (len(ill) == 0): continue il_print(ill, fpol) if __name__=='__main__': main()