Wie kann ich über Dateien in einem bestimmten Verzeichnis iterieren?

555

Ich muss alles durchlaufen .asm Dateien in einem bestimmten Verzeichnis und einige Aktionen ausführen.

Wie kann dies effizient durchgeführt werden?

Itzik984
quelle

Antworten:

807

Ursprüngliche Antwort:

import os

for filename in os.listdir(directory):
    if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
        continue
    else:
        continue

Python 3.6-Version der obigen Antwort unter Verwendung von os- vorausgesetzt, Sie haben den Verzeichnispfad als strObjekt in einer Variablen namens directory_in_str:

import os

directory = os.fsencode(directory_in_str)

for file in os.listdir(directory):
     filename = os.fsdecode(file)
     if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
         continue
     else:
         continue

Oder rekursiv mit pathlib:

from pathlib import Path

pathlist = Path(directory_in_str).glob('**/*.asm')
for path in pathlist:
     # because path is object not string
     path_in_str = str(path)
     # print(path_in_str)
Anselm
quelle
1
Dies scheint nur die Verzeichnisse oder Dateien unmittelbar unter einem Verzeichnis aufzulisten. Die Antwort von pedromateo unten scheint eine rekursive Auflistung zu machen.
Jay Sheth
8
Bitte beachten Sie, dass im Python 3.6-Verzeichnis erwartet wird, dass es sich um Bytes handelt, und dass listdir dann eine Liste von Dateinamen auch im Byte-Datentyp ausspuckt, sodass Sie Endswith nicht direkt darauf ausführen können. Dieser Codeblock sollte geändert werden indirectory = os.fsencode(directory_in_str) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".asm") or filename.endswith(".py"): # print(os.path.join(directory, filename)) continue else: continue
Kim Stacks
13
print(os.path.join(directory, filename))müssen geändert werden, print(os.path.join(directory_in_str, filename))damit es in Python 3.6 funktioniert
Hugo Koopmans
54
Wenn Sie dies 2017 oder darüber hinaus sehen, ist os.scandir (dir_str) jetzt verfügbar und viel sauberer zu verwenden. Kein Fsencode erforderlich. for entry in os.scandir(path): print(entry.path)
Ziege
2
Bevorzugen if filename.endswith((".asm", ".py")):zuif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio
152

Dadurch werden alle untergeordneten Dateien durchlaufen, nicht nur die unmittelbaren untergeordneten Dateien des Verzeichnisses:

import os

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        #print os.path.join(subdir, file)
        filepath = subdir + os.sep + file

        if filepath.endswith(".asm"):
            print (filepath)
pedromateo
quelle
3
Eine Referenz für die os.walk-Funktion finden Sie unter: docs.python.org/2/library/os.path.html#os.path.walk
ScottMcC
136

Sie können versuchen, das Glob- Modul zu verwenden:

import glob

for filepath in glob.iglob('my_dir/*.asm'):
    print(filepath)

und seit Python 3.5 können Sie auch Unterverzeichnisse durchsuchen:

glob.glob('**/*.txt', recursive=True) # => ['2.txt', 'sub/3.txt']

Aus den Dokumenten:

Das Glob-Modul findet alle Pfadnamen, die einem bestimmten Muster gemäß den von der Unix-Shell verwendeten Regeln entsprechen, obwohl die Ergebnisse in beliebiger Reihenfolge zurückgegeben werden. Es wird keine Tilde-Erweiterung durchgeführt, aber *,? Und Zeichenbereiche, die mit [] ausgedrückt werden, werden korrekt abgeglichen.

Doboy
quelle
19

Seit Python 3.5 ist es mit os.scandir ( ) viel einfacher

with os.scandir(path) as it:
    for entry in it:
        if entry.name.endswith(".asm") and entry.is_file():
            print(entry.name, entry.path)

Die Verwendung von scandir () anstelle von listdir () kann die Leistung von Code erheblich verbessern, der auch Dateityp- oder Dateiattributinformationen benötigt, da os.DirEntry-Objekte diese Informationen verfügbar machen, wenn das Betriebssystem sie beim Scannen eines Verzeichnisses bereitstellt. Alle os.DirEntry-Methoden können einen Systemaufruf ausführen, aber is_dir () und is_file () erfordern normalerweise nur einen Systemaufruf für symbolische Links. os.DirEntry.stat () erfordert unter Unix immer einen Systemaufruf, unter Windows jedoch nur einen für symbolische Links.

Crypdick
quelle
entryist ein posix.DirEntry Typ mit einem Bündel von praktischen Methoden wie entry.is_dir(), is_file(),is_symlink()
crypdick
17

Python 3.4 und höher bieten pathlib in der Standardbibliothek an. Du könntest es tun:

from pathlib import Path

asm_pths = [pth for pth in Path.cwd().iterdir()
            if pth.suffix == '.asm']

Oder wenn Sie Listenverständnisse nicht mögen:

asm_paths = []
for pth in Path.cwd().iterdir():
    if pth.suffix == '.asm':
        asm_pths.append(pth)

Path Objekte können einfach in Zeichenfolgen konvertiert werden.

Greg
quelle
9

So iteriere ich durch Dateien in Python:

import os

path = 'the/name/of/your/path'

folder = os.fsencode(path)

filenames = []

for file in os.listdir(folder):
    filename = os.fsdecode(file)
    if filename.endswith( ('.jpeg', '.png', '.gif') ): # whatever file types you're using...
        filenames.append(filename)

filenames.sort() # now you have the filenames and can do something with them

KEINE DIESER TECHNIKEN GARANTIERT JEDE ITERATIONSBESTELLUNG

Ja, super unberechenbar. Beachten Sie, dass ich die Dateinamen sortiere, was wichtig ist, wenn die Reihenfolge der Dateien wichtig ist, dh für Videobilder oder zeitabhängige Datenerfassung. Stellen Sie jedoch sicher, dass Ihre Dateinamen Indizes enthalten!

Daniel McGrath
quelle
Nicht immer sortiert ... im1, im10, im11 ..., im2 ... Ansonsten nützlicher Ansatz. from pkg_resources import parse_versionund filenames.sort(key=parse_version)tat es.
Hastur
5

Sie können glob verwenden, um auf das Verzeichnis und die Liste zu verweisen:

import glob
import os

#to get the current working directory name
cwd = os.getcwd()
#Load the images from images folder.
for f in glob.glob('images\*.jpg'):   
    dir_name = get_dir_name(f)
    image_file_name = dir_name + '.jpg'
    #To print the file name with path (path will be in string)
    print (image_file_name)

Um die Liste aller Verzeichnisse im Array abzurufen, können Sie os verwenden :

os.listdir(directory)
YAP
quelle
4

Ich bin noch nicht ganz zufrieden mit dieser Implementierung. Ich wollte einen benutzerdefinierten Konstruktor, der dies tut DirectoryIndex._make(next(os.walk(input_path))), sodass Sie einfach den Pfad übergeben können, für den Sie eine Dateiliste wünschen. Änderungen willkommen!

import collections
import os

DirectoryIndex = collections.namedtuple('DirectoryIndex', ['root', 'dirs', 'files'])

for file_name in DirectoryIndex(*next(os.walk('.'))).files:
    file_path = os.path.join(path, file_name)
ThorSummoner
quelle
2

Ich verwende sehr gerne die scandirDirektive, die in die osBibliothek integriert ist. Hier ist ein Arbeitsbeispiel:

import os

i = 0
with os.scandir('/usr/local/bin') as root_dir:
    for path in root_dir:
        if path.is_file():
            i += 1
            print(f"Full path is: {path} and just the name is: {path.name}")
print(f"{i} files scanned successfully.")
Jamescampbell
quelle
doppelte Antwort
Crypdick