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.

3voto

gerrit Punkte 20354

Wenn sich die Dateien auf einem entferntes Dateisystem o innerhalb eines Archivs können Sie eine Implementierung der Methode fsspec AbstractFileSystem-Klasse . Zum Beispiel, um alle Dateien in einer Zip-Datei aufzulisten:

from fsspec.implementations.zip import ZipFileSystem
fs = ZipFileSystem("/tmp/test.zip")
fs.glob("/**")  # equivalent: fs.find("/")

oder um alle Dateien in einem öffentlich zugänglichen S3-Bucket aufzulisten:

from s3fs import S3FileSystem
fs_s3 = S3FileSystem(anon=True)
fs_s3.glob("noaa-goes16/ABI-L1b-RadF/2020/045/**")  # or use fs_s3.find

können Sie es auch für ein lokales Dateisystem verwenden, was interessant sein kann, wenn Ihre Implementierung dateisystemunabhängig sein soll:

from fsspec.implementations.local import LocalFileSystem
fs = LocalFileSystem()
fs.glob("/tmp/test/**")

Andere Implementierungen umfassen Google Cloud, Github, SFTP/SSH, Dropbox und Azure. Einzelheiten finden Sie in der fsspec API-Dokumentation .

3voto

xtofl Punkte 39285

Oder mit einem Listenverständnis:

 >>> base = r"c:\User\xtofl"
 >>> binfiles = [ os.path.join(base,f) 
            for base, _, files in os.walk(root) 
            for f in files if f.endswith(".jpg") ]

3voto

chris-piekarski Punkte 988

Eine andere Möglichkeit ist, nur das glob-Modul zu verwenden. Geben Sie der rglob-Methode einfach ein Basisverzeichnis und ein Muster für die Suche vor, und sie gibt eine Liste der passenden Dateinamen zurück.

import glob
import os

def _getDirs(base):
    return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ]

def rglob(base, pattern):
    list = []
    list.extend(glob.glob(os.path.join(base,pattern)))
    dirs = _getDirs(base)
    if len(dirs):
        for d in dirs:
            list.extend(rglob(os.path.join(base,d), pattern))
    return list

2voto

f0xdx Punkte 1199

Zusätzlich zu den vorgeschlagenen Antworten können Sie dies mit ein wenig Zauberei bei der Generierung und dem Verstehen von Listen erreichen:

import os, glob, itertools

results = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.c'))
                                               for root, dirs, files in os.walk('src'))

for f in results: print(f)

Dies passt nicht nur in eine Zeile und vermeidet unnötige Listen im Speicher, sondern hat auch den netten Nebeneffekt, dass man es ähnlich wie den **-Operator verwenden kann, z.B. könnte man os.path.join(root, 'some/path/*.c') um alle .c-Dateien in allen Unterverzeichnissen von src zu erhalten, die diese Struktur haben.

2voto

hipertracker Punkte 2310

Dieser verwendet fnmatch oder einen regulären Ausdruck:

import fnmatch, os

def filepaths(directory, pattern):
    for root, dirs, files in os.walk(directory):
        for basename in files:
            try:
                matched = pattern.match(basename)
            except AttributeError:
                matched = fnmatch.fnmatch(basename, pattern)
            if matched:
                yield os.path.join(root, basename)

# usage
if __name__ == '__main__':
    from pprint import pprint as pp
    import re
    path = r'/Users/hipertracker/app/myapp'
    pp([x for x in filepaths(path, re.compile(r'.*\.py$'))])
    pp([x for x in filepaths(path, '*.py')])

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