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.

9voto

Daniel Punkte 1129

Für den Fall, dass sich jemand dafür interessiert, habe ich ein Profil der drei wichtigsten vorgeschlagenen Methoden erstellt. Ich habe etwa 500.000 Dateien im Ordner "globbed" (insgesamt) und 2.000 Dateien, die dem gewünschten Muster entsprechen.

Hier ist der (sehr einfache) Code

import glob
import json
import fnmatch
import os
from pathlib import Path
from time import time

def find_files_iglob():
    return glob.iglob("./data/**/data.json", recursive=True)

def find_files_oswalk():
    for root, dirnames, filenames in os.walk('data'):
        for filename in fnmatch.filter(filenames, 'data.json'):
            yield os.path.join(root, filename)

def find_files_rglob():
    return Path('data').rglob('data.json')

t0 = time()
for f in find_files_oswalk(): pass    
t1 = time()
for f in find_files_rglob(): pass
t2 = time()
for f in find_files_iglob(): pass 
t3 = time()
print(t1-t0, t2-t1, t3-t2)

Und die Ergebnisse waren:
os_walk: ~3.6sec
rglob ~14.5sec
iglob: ~16.9sec

Die Plattform: Ubuntu 16.04, x86_64 (Core i7),

7voto

Mustafa Çetin Punkte 101

Vor kurzem musste ich meine Bilder mit der Endung .jpg wiederherstellen. Ich habe photorec ausgeführt und 4579 Verzeichnisse mit 2,2 Millionen Dateien wiederhergestellt, die eine enorme Vielfalt an Erweiterungen aufweisen. Mit dem untenstehenden Skript konnte ich innerhalb von Minuten 50133 Dateien mit der Erweiterung .jpg auswählen:

#!/usr/binenv python2.7

import glob
import shutil
import os

src_dir = "/home/mustafa/Masaüstü/yedek"
dst_dir = "/home/mustafa/Genel/media"
for mediafile in glob.iglob(os.path.join(src_dir, "*", "*.jpg")): #"*" is for subdirectory
    shutil.copy(mediafile, dst_dir)

6voto

daveoncode Punkte 17391

Basierend auf anderen Antworten ist dies meine aktuelle Arbeitsimplementierung, die verschachtelte XML-Dateien in einem Root-Verzeichnis abruft:

files = []
for root, dirnames, filenames in os.walk(myDir):
    files.extend(glob.glob(root + "/*.xml"))

Ich habe wirklich Spaß an Python :)

6voto

Sami Punkte 7844

Für Python 3.5 und höher

import glob

#file_names_array = glob.glob('path/*.c', recursive=True)
#above works for files directly at path/ as guided by NeStack

#updated version
file_names_array = glob.glob('path/**/*.c', recursive=True)

weiter benötigen Sie vielleicht

for full_path_in_src in  file_names_array:
    print (full_path_in_src ) # be like 'abc/xyz.c'
    #Full system path of this would be like => 'path till src/abc/xyz.c'

5voto

Andrew Alcock Punkte 18981

Johan und Bruno bieten hervorragende Lösungen für die angegebenen Mindestanforderungen. Ich habe gerade veröffentlicht Ameisensäure die Ant implementiert FileSet und Globs die diese und kompliziertere Szenarien bewältigen kann. Eine Umsetzung Ihrer Anforderung ist:

import formic
fileset = formic.FileSet(include="/src/**/*.c")
for file_name in fileset.qualified_files():
    print file_name

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