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.

42voto

Alex Martelli Punkte 805329
import os
import fnmatch

def recursive_glob(treeroot, pattern):
    results = []
    for base, dirs, files in os.walk(treeroot):
        goodfiles = fnmatch.filter(files, pattern)
        results.extend(os.path.join(base, f) for f in goodfiles)
    return results

fnmatch gibt Ihnen genau die gleichen Muster wie glob Dies ist also ein hervorragender Ersatz für glob.glob mit sehr enger Semantik. Eine iterative Version (z. B. ein Generator), d. h. ein Ersatz für glob.iglob ist eine triviale Anpassung (nur yield die Zwischenergebnisse nach und nach, anstatt extend in einer einzigen Ergebnisliste, die am Ende zurückgegeben wird).

22voto

Geoff Reedy Punkte 33293

Sie werden Folgendes verwenden wollen os.walk um Dateinamen zu sammeln, die Ihren Kriterien entsprechen. Zum Beispiel:

import os
cfiles = []
for root, dirs, files in os.walk('src'):
  for file in files:
    if file.endswith('.c'):
      cfiles.append(os.path.join(root, file))

17voto

akaihola Punkte 25244

Hier ist eine Lösung mit verschachtelten Listenauffassungen, os.walk und einfache Suffixabgleiche anstelle von glob :

import os
cfiles = [os.path.join(root, filename)
          for root, dirnames, filenames in os.walk('src')
          for filename in filenames if filename.endswith('.c')]

Sie kann auf einen Einzeiler komprimiert werden:

import os;cfiles=[os.path.join(r,f) for r,d,fs in os.walk('src') for f in fs if f.endswith('.c')]

oder verallgemeinert als Funktion:

import os

def recursive_glob(rootdir='.', suffix=''):
    return [os.path.join(looproot, filename)
            for looproot, _, filenames in os.walk(rootdir)
            for filename in filenames if filename.endswith(suffix)]

cfiles = recursive_glob('src', '.c')

Wenn Sie eine vollständige glob Stilmustern, können Sie Alex' und Brunos Beispiel folgen und die fnmatch :

import fnmatch
import os

def recursive_glob(rootdir='.', pattern='*'):
    return [os.path.join(looproot, filename)
            for looproot, _, filenames in os.walk(rootdir)
            for filename in filenames
            if fnmatch.fnmatch(filename, pattern)]

cfiles = recursive_glob('src', '*.c')

11voto

pylang Punkte 33775

Erwägen Sie pathlib.rglob() .

Das ist so, als würde man Path.glob() con "**/" vor dem angegebenen relativen Muster hinzugefügt:

import pathlib

for p in pathlib.Path("src").rglob("*.c"):
    print(p)

Siehe auch @taleinat's related Beitrag hier und ein ähnliches Beitrag anderswo.

11voto

import os, glob

for each in glob.glob('path/**/*.c', recursive=True):
    print(f'Name with path: {each} \nName without path: {os.path.basename(each)}')
  • glob.glob('*.c') :findet alle Dateien, die auf .c im aktuellen Verzeichnis
  • glob.glob('*/*.c') :wie bei 1
  • glob.glob('**/*.c') :findet alle Dateien, die auf .c nur in den unmittelbaren Unterverzeichnissen, aber nicht im aktuellen Verzeichnis
  • glob.glob('*.c',recursive=True) :wie bei 1
  • glob.glob('*/*.c',recursive=True) :wie bei 3
  • glob.glob('**/*.c',recursive=True) :findet alle Dateien, die auf .c im aktuellen Verzeichnis und in allen Unterverzeichnissen

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