«найти». -regex… »в Python или Как найти файлы, полное имя которых (путь + имя) соответствует регулярному выражению?

Я хотел бы найти файлы, полное имя которых (относительное, хотя и абсолютное тоже неплохо) соответствует заданному регулярному выражению (например, как glob , но для совпадений регулярных выражений вместо совпадений с подстановочными знаками оболочки). Используя find , можно было бы сделать, например:

find . -regex ./foo/\w+/bar/[0-9]+-\w+.dat

Конечно, я мог бы использовать find через os.system (...) или os.exec * (...) , но я ищу решение на чистом Python. Следующий код объединяет os.walk (...) с регулярными выражениями модуля re - это простое решение Python (оно ненадежно и пропускает многие (не такие уж угловатые) угловые случаи, но это достаточно хорошо gh для моего одноразового использования, поиска определенных файлов данных для одноразовой вставки в базу данных.)

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

Но это неэффективно. Поддеревья, содержимое которых не может соответствовать регулярному выражению (например, ./ foo / \ w + / baz / , чтобы продолжить пример выше), обходятся без необходимости. В идеале эти поддеревья следует обрезать с пути; любой подкаталог, путь которого не является частичным совпадением с регулярным выражением, не должен проходить. (Я предполагаю, что GNU find реализует такую ​​оптимизацию, но я не подтвердил это с помощью тестов или изучения исходного кода.)

Кто-нибудь знает о Python-реализации надежного find , в идеале с оптимизацией удаления поддерева? Я надеюсь, что мне просто не хватает метода в модуле os.path или в каком-либо стороннем модуле.

10
задан David B. 23 July 2011 в 18:54
поделиться