1019 Stimmen

Wie kann man glob() verwenden, um Dateien rekursiv zu finden?

Das habe ich:

glob(os.path.join('src','*.c'))

aber ich möchte die Unterordner von src durchsuchen. Etwas wie dies würde funktionieren:

glob(os.path.join('src','*.c'))
glob(os.path.join('src','*','*.c'))
glob(os.path.join('src','*','*','*.c'))
glob(os.path.join('src','*','*','*','*.c'))

Aber das ist natürlich begrenzt und unhandlich.

1797voto

Johan Dahlin Punkte 23232

pathlib.Path.rglob

Utilisez pathlib.Path.rglob vom pathlib Modul, das in Python 3.5 eingeführt wurde.

from pathlib import Path

for path in Path('src').rglob('*.c'):
    print(path.name)

Wenn Sie pathlib nicht verwenden möchten, können Sie glob.glob('**/*.c') , aber vergessen Sie nicht, die recursive und verbraucht bei großen Verzeichnissen unangemessen viel Zeit.

Für Fälle, in denen passende Dateien, die mit einem Punkt ( . ); wie Dateien im aktuellen Verzeichnis oder versteckte Dateien auf Unix-basierten Systemen, verwenden Sie die os.walk Lösung unten.

os.walk

Für ältere Python-Versionen, verwenden Sie os.walk um ein Verzeichnis rekursiv zu durchsuchen und fnmatch.filter um mit einem einfachen Ausdruck übereinzustimmen:

import fnmatch
import os

matches = []
for root, dirnames, filenames in os.walk('src'):
    for filename in fnmatch.filter(filenames, '*.c'):
        matches.append(os.path.join(root, filename))

212voto

Pedro Lobito Punkte 84666

Für python >= 3.5 können Sie ** , recursive=True :

import glob
for f in glob.glob('/path/**/*.c', recursive=True):
    print(f)

Wenn rekursiv ist True das Muster ** passt auf alle Dateien und null oder mehr directories y subdirectories . Wenn auf das Muster ein ein os.sep nur Verzeichnisse und subdirectories übereinstimmen.


Python 3.6 Demo

122voto

Bruno Oliveira Punkte 11772

Ähnlich wie andere Lösungen, aber unter Verwendung von fnmatch.fnmatch anstelle von glob, da os.walk die Dateinamen bereits aufgelistet hat:

import os, fnmatch

def find_files(directory, pattern):
    for root, dirs, files in os.walk(directory):
        for basename in files:
            if fnmatch.fnmatch(basename, pattern):
                filename = os.path.join(root, basename)
                yield filename

for filename in find_files('src', '*.c'):
    print 'Found C source:', filename

Außerdem können Sie mit einem Generator jede Datei verarbeiten, wenn sie gefunden wird, anstatt alle Dateien zu suchen und dann sie zu bearbeiten.

93voto

miracle2k Punkte 25301

Ich habe das glob-Modul so geändert, dass es ** für rekursives globbing unterstützt, z.B:

>>> import glob2
>>> all_header_files = glob2.glob('src/**/*.c')

https://github.com/miracle2k/python-glob2/

Nützlich, wenn Sie Ihren Benutzern die Möglichkeit geben wollen, die **-Syntax zu verwenden, und daher os.walk() allein nicht ausreicht.

79voto

taleinat Punkte 8111

Beginnend mit Python 3.4 kann man die glob() Methode einer der Path Klassen in der neuen pathlib Modul, das Folgendes unterstützt ** Wildcards. Zum Beispiel:

from pathlib import Path

for file_path in Path('src').glob('**/*.c'):
    print(file_path) # do whatever you need with these files

Aktualisierung: Ab Python 3.5 wird die gleiche Syntax auch von glob.glob() .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X