Ich möchte Dateien finden, deren gesamter Name (relativ, aber auch absolut) mit einem bestimmten regulären Ausdruck übereinstimmt (z. B. wie der glob
Modul, aber für Regex-Matches anstelle von Shell-Wildcard-Matches). Verwendung von find
Eine würde zum Beispiel ausreichen:
find . -regex ./foo/\w+/bar/[0-9]+-\w+.dat
Natürlich könnte ich die find
über os.system(...)
o os.exec*(...)
aber ich bin auf der Suche nach einer reinen Python-Lösung. Der folgende Code kombiniert os.walk(...)
con re
Modul reguläre Ausdrücke ist eine einfache Python-Lösung. (Es ist nicht robust und lässt viele (nicht ganz so eckige) Fälle aus, aber es ist gut genug für meine Einmalige Verwendung, Auffinden bestimmter Datendateien für eine einmalige Datenbankeinfügung).
import os
import re
def find(regex, top='.'):
matcher = re.compile(regex)
for dirpath, dirnames, filenames in os.walk(top):
for f in filenames:
f = os.path.relpath(os.path.join(dirpath, f), top)
if matcher.match(f):
yield f
if __name__=="__main__":
top = "."
regex = "foo/\w+/bar/\d+-\w+.dat"
for f in find(regex, top):
print f
Dies ist jedoch ineffizient. Teilbäume, deren Inhalt nicht mit dem Regex übereinstimmen kann (z. B., ./foo/\w+/baz/
(um das obige Beispiel fortzusetzen) werden unnötigerweise gelaufen. Idealerweise sollten diese Teilbäume aus der Suche herausgenommen werden; jedes Unterverzeichnis, dessen Pfadname keine Teilübereinstimmung mit dem Regex ist, sollte nicht durchlaufen werden. (Ich würde vermuten, dass GNU find
implementiert eine solche Optimierung, aber ich habe dies nicht durch Tests oder Einsicht in den Quellcode bestätigt).
Kennt jemand eine Python-Implementierung eines robusten Regex-basierten find
, idealerweise mit Subtree-Pruning-Optimierung? Ich hoffe, dass ich nur eine Methode in der Datenbank vermisse. os.path
Modul oder ein Modul eines Drittanbieters.