############################################################################## # Module: search.py # Author: Matthias Delhey # Date: 02.12.2009 - 21.01.2010 # Version: 1.5 ''' Suchstring-Tool =============== Zweck: In einem Verzeichnis alle Dateien bestimmter Typen nach String durchsuchen und Ergebnisse in 'FOUNDSTRING.txt' im Such-Verzeichnis speichern Verwendung: python search.py python search.pyc - damit sich das Script nicht selbst durchsucht! import search -> search.findInStrFiles() -> search.findInStrFiles("D:\\AutoLISP\\", [".lsp", ".dcl"]) Docstrings: python -> import search -> print seach.__doc__ -> print search.findStrInFiles.__doc__ Inhalt: class findStrInFiles Vorraussetzungen: os Optional: pyGTK ''' ############################### # Log: # 02.12.2009 - Draft # 03.12.2009 - 1.0 laeuft # 16.12.2009 - 1.1 Lauffaehigkeit ohne GTK implementiert # Commandline Parameteruebergabe ermoeglicht # 17.12.2009 - 1.2 Hilfe ergaenzt/Ergebnisdatei von Suche ausgenommen # 20.01.2009 - 1.4 Suchstring-Dialog kann jetzt mit Enter beendet werden # und startet zentriert/GTK-Funktion gestrafft # 21.01.2009 - 1.5 Vorgabe-Suchstring aus Ergebnisdatei generieren # Ergebnis-Datei immer im Such-Verzeichnis speichern # Fenster-Icon geaendert # Windows-Umlaute-Kompatibilitaet eingebaut (ISO-8859-1) ############################################################################## noGTK = False try: import pygtk pygtk.require('2.0') import gtk except ImportError: noGTK = True import os, sys #***************************************************************************** class findStrInFiles: """ In Verzeichnis alle Dateien bestimmter Typen nach String durchsuchen args: dirName - opt., String, Verzeichnispfad, Vorgabe: aktuelles Verz. fileExtLst - opt., String Liste, z.B.: ['.py', '.txt'], Vorg.: ['.py'] -> Textdatei 'FOUNDSTRING.txt' mit Suchergebnis schreiben z.B.: findStrInFiles() findStrInFiles("D:\\Projekte\\AutoLISP\\Projekt", [".lsp", ".dcl"]) """ CODING = 'ISO-8859-1' #zu verwendendes Encoding SEARCHDIR = os.getcwd() #Suchverzeichnis /aktuelles Verzeichnis = Vorgabe FILEEXTLST = ['.py'] #Liste der zu beruecksichtigenden Dateiendungen FILELST = [] #Liste mit zu durchsuchenden Dateien TEXTLST = [] #Liste mit String-Listen LASTSEARCHSTR = None #letzter Searchstring (aus RESFILENAME holen) SEARCHSTR = None #Suchstring nach Usereingabe RESLST = [] #Ergebnisliste der Suchaktion SEP = "========================================================================\n" RESFILENAME = "FOUNDSTRING.txt" #Dateiname fuer Ergebnisausgabe ERROR = False #wenn 'True': Fehlerstring speichern def tryGetOldSearchStr(self): """versuchen, einen Vorgabe-Suchstring aus Ergebnisdatei zu generieren """ fileNam = None tryFileNam = self.SEARCHDIR + os.sep + self.RESFILENAME if os.path.isfile(tryFileNam): fileNam = tryFileNam else: if os.path.isfile(self.RESFILENAME): fileNam = self.RESFILENAME if fileNam: f = file(fileNam) line = f.readline() f.close() if line not in ['', '\n']: tmp = line.split('<') if len(tmp) > 1: tmp = tmp[1].split('>') if len(tmp) > 1: self.LASTSEARCHSTR = tmp[0].decode(self.CODING) def getSearchStr(self): """Such-String von User holen """ if noGTK: self.SEARCHSTR = raw_input('\n->Suchstring: ') #Commandline-Eingabe ohne GTK! else: self.tryGetOldSearchStr() #versuchen letzten SuchSting als Vorgabe zu holen #GTK-Dialog: dialog = gtk.Dialog("Dateien durchsuchen...") dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS) icon = dialog.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_BUTTON) dialog.set_icon(icon) #Box mit Label: box = gtk.HBox(False, 15) label = gtk.Label("Suchstring:") box.pack_start(label, True, True, 15) entry = gtk.Entry() entry.set_activates_default(True) if self.LASTSEARCHSTR: entry.set_text(self.LASTSEARCHSTR) box.pack_start(entry, True, True, 15) dialog.vbox.pack_start(box, True, True, 15) #Ok-Cancel Button: dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.set_default_response(gtk.RESPONSE_OK) dialog.show_all() #Dialogbox starten res = dialog.run() text = entry.get_text() dialog.destroy() if res == gtk.RESPONSE_OK: self.SEARCHSTR = text.encode(self.CODING) if self.SEARCHSTR: return True #wenn Dialogbox erfolgreich den Suchstring gesetzt hat def setFileLst(self): """Dateinamen-Liste setzen """ if os.path.isdir(self.SEARCHDIR): tmp = os.listdir(self.SEARCHDIR) if tmp != []: tmp = sorted(tmp) if self.RESFILENAME in tmp: tmp.remove(self.RESFILENAME) #Ergebnisdatei ggf. ausnehmen for ele in tmp: for i in self.FILEEXTLST: if ele.endswith(i): self.FILELST.append(self.SEARCHDIR + os.sep + ele) #Dateinamen mit entsprechender Endung if self.FILELST == []: self.ERROR = "keine passenden Dateien gefunden!" else: self.ERROR = "keine Dateien in Verzeichnis gefunden!" else: self.ERROR = "Verzeichnis ungueltig!" if not self.ERROR: return True #alles klar! def setTextLst(self): """Textliste mit Stringlines aller Dateien anlegen """ for i in self.FILELST: #jede Datei auslesen: f = file(i) lst = f.readlines() f.close() if lst != []: self.TEXTLST.append([i] + lst) #mit Dateinamen an 1.Pos in Textliste speichern if self.TEXTLST == []: self.ERROR = "alle Dateien sind leer!???" else: return True #alles klar! def makeHitLst(self): """Textliste nach Suchstring durchsuchen und Trefferliste in Datei speichern """ for strLst in self.TEXTLST: n = 1; tmp = [self.SEP, strLst[0]+":\n", "\n"] #Dateiname an 1.Pos uebernehmen for s in strLst[1:]: if s.find(self.SEARCHSTR) >= 0: #wenn Suchstring in Stringline vorkommt: tmp.append(str(n).rjust(4, ' ') + " - " + s) #mit Zeilennummer speichern n += 1 if len(tmp) > 3: self.RESLST = self.RESLST + tmp if self.RESLST != []: self.RESLST = ["Suchstring <" + self.SEARCHSTR + "> gefunden in:\n"] + self.RESLST self.RESLST.append(self.SEP) res = True #fuer Rueckgabe else: self.RESLST = "Suchstring <" + self.SEARCHSTR + "> kommt nicht vor!\n" res = None #fuer Rueckgabe f = file(self.SEARCHDIR + os.sep + self.RESFILENAME, "w") #Ergebnis in Datei schreiben f.writelines(self.RESLST) f.close() return res def __init__(self, dirName=None, fileExtLst=None): """Konstruktor = Hauptfunktion mit gesamten Programmablauf: (!?) """ if dirName: self.SEARCHDIR = dirName #wenn Verz.-Name uebergeben wurde if fileExtLst: self.FILEEXTLST = fileExtLst #wenn Dateiendungsliste -"- -"- if self.setFileLst(): #zu durchsuchende Dateien finden/holen if self.setTextLst(): #Inhalt der Dateien auslesen und speichern if self.getSearchStr(): #Searchstring von User holen if self.makeHitLst(): #Suchstring finden und in Datei schreiben def printLst(x): print x.strip("\n").decode(self.CODING) #Hilfsfunktion um alle Str einer Liste zu printen print "\n"; map(printLst, self.RESLST) print "\nErgebnisse in <" + self.SEARCHDIR + os.sep + self.RESFILENAME + "> gespeichert!" else: print "Suchstring <" + self.SEARCHSTR.decode(self.CODING) + "> kommt nicht vor!" else: print "kein Suchstring eingegeben!" else: print self.ERROR else: print self.ERROR #***************************************************************************** if __name__ == "__main__": paraLst = sys.argv #Commandline Aufrufparameter if len(paraLst) > 1: #wenn nach 'search.py' zusaetzliche Parameter an python uebergeben wurden if paraLst[1].upper() in ['-H','H','-HELP','HELP','-?','?','-HILFE','HILFE']: print ("\n-> als ersten Parameter bitte ein gueltiges Suchverzeichnis angeben" + "\n z.B.: '.' fuer aktuelles Verzeichnis (ist auch Vorgabe) oder 'C:\daten' etc" + "\n-> alle weiteren Parameter koennen Textdateiendungen sein z.B.: py txt lsp etc\n" + "\n Beispiele: " + "\n -> 'python search.py D:\\python\\tools py txt' " + "\n (durchsucht '.py' und '.txt'-Dateien in 'D:\\python\\tools')\n" + "\n -> 'python search.py ..\modules'" + "\n (durchsucht im Nachbarverzeichnis alle '.py'-Dateien (Vorgabe))\n" + "\n -> 'python search.pyc . dcl lsp'" + "\n (durchsucht '.dcl' und '.lsp'-Dateien im aktuellen Verzeichnis" + "\n statt '.' kann auch '-' oder 'None' fuer aktuelles Verzeichnis" + "\n verwendet werden)") else: dir = None; fileExt = None if os.path.isdir(paraLst[1]): dir = paraLst[1] #ersten Parameter als Suchverzeichnis speichern if paraLst[2:] != []: #wenn es darueber hinaus noch Parameter gibt: fileExt = [] #sollten es Dateiendungen sein for i in paraLst[2:]: if not i.startswith('.'): fileExt.append('.' + i) #Punkte ergaenzen wenn noetig else: fileExt.append(i) findStrInFiles(dir, fileExt) #Parameter an 'findStrInFiles' uebergeben else: findStrInFiles() #ohne Parameter aufgerufen #--------------------------------------------------------------------------EOF