Ich habe einen C ++ / Obj-C-Hintergrund und entdecke gerade Python (schreibe es seit ungefähr einer Stunde). Ich schreibe ein Skript, um den Inhalt von Textdateien in einer Ordnerstruktur rekursiv zu lesen.
Das Problem, das ich habe, ist, dass der Code, den ich geschrieben habe, nur für einen Ordner tief funktioniert. Ich kann sehen, warum ich im Code (siehe #hardcoded path
) nicht weiß, wie ich mit Python vorankommen kann, da meine Erfahrung damit nur brandneu ist.
Python-Code:
import os
import sys
rootdir = sys.argv[1]
for root, subFolders, files in os.walk(rootdir):
for folder in subFolders:
outfileName = rootdir + "/" + folder + "/py-outfile.txt" # hardcoded path
folderOut = open( outfileName, 'w' )
print "outfileName is " + outfileName
for file in files:
filePath = rootdir + '/' + file
f = open( filePath, 'r' )
toWrite = f.read()
print "Writing '" + toWrite + "' to" + filePath
folderOut.write( toWrite )
f.close()
folderOut.close()
os.walk
nicht schlecht ist, obwohl ich mir einen noch schnelleren Weg über ausgedacht habeos.scandir
. Alleglob
Lösungen sind viel langsamer alswalk
&scandir
. Meine Funktion sowie eine vollständige Geschwindigkeitsanalyse finden Sie hier: stackoverflow.com/a/59803793/2441026Wenn Sie Python 3.5 oder höher verwenden, können Sie dies in einer Zeile erledigen.
Wie in der Dokumentation erwähnt
Wenn Sie jede Datei möchten, können Sie verwenden
quelle
root_dir
Schrägstrich benötigt? Dies spart den Leuten Zeit (oder zumindest hätte es mir Zeit gespart). Vielen Dank.glob.iglob(root_dir + '**/**', recursive=True)
. Ich arbeite in Python 3.8.2Wenn Sie mit Dave Webb einverstanden sind,
os.walk
erhalten Sie für jedes Verzeichnis im Baum ein Element. Tatsache ist, dass Sie sich einfach nicht darum kümmern müssensubFolders
.Code wie dieser sollte funktionieren:
quelle
TL; DR: Dies entspricht dem
find -type f
Durchsuchen aller Dateien in allen Ordnern unten und einschließlich der aktuellen:Wie bereits in anderen Antworten erwähnt,
os.walk()
ist die Antwort, aber es könnte besser erklärt werden. Es ist ganz einfach! Gehen wir durch diesen Baum:Mit diesem Code:
Dies
currentpath
ist der aktuelle Ordner, den es sich ansieht. Dies wird Folgendes ausgeben:Es wird also dreimal wiederholt, da drei Ordner vorhanden sind: der aktuelle ,,
docs
undpics
. In jeder Schleife werden die Variablenfolders
undfiles
alle Ordner und Dateien gefüllt. Zeigen wir ihnen:Das zeigt uns:
In der ersten Zeile sehen wir also
.
, dass wir uns in einem Ordner befinden , dass er zwei Ordner enthält, nämlichpics
unddocs
, und dass es eine Datei gibt, nämlichtodo.txt
. Sie müssen nichts tun, um in diese Ordner zurückzukehren, da es, wie Sie sehen, automatisch wiederholt wird und Sie nur die Dateien in beliebigen Unterordnern erhalten. Und alle Unterordner davon (obwohl wir diese im Beispiel nicht haben).Wenn Sie nur alle Dateien durchlaufen möchten
find -type f
, können Sie Folgendes tun:Dies gibt aus:
quelle
Die
pathlib
Bibliothek eignet sich hervorragend zum Arbeiten mit Dateien. Sie können einen rekursiven Glob für einPath
Objekt wie dieses erstellen .quelle
Wenn Sie eine flache Liste aller Pfade unter einem bestimmten Verzeichnis wünschen (wie
find .
in der Shell):Lassen Sie es weg, um nur vollständige Pfade zu Dateien unter dem Basisverzeichnis einzuschließen
+ subdirs
.quelle
**/**
wird verwendet, um alle Dateien einschließlich rekursiv abzurufendirectory
.if os.path.isfile(filename)
wird verwendet, um zu überprüfen, ob einefilename
Variable istfile
oderdirectory
ob es sich um eine Datei handelt, dann können wir diese Datei lesen. Hier drucke ich Datei.quelle
Ich habe Folgendes als am einfachsten empfunden
Mit using werden
glob('some/path/**', recursive=True)
alle Dateien abgerufen, aber auch Verzeichnisnamen. Durch Hinzufügen derif os.path.isfile(f)
Bedingung wird diese Liste nur für vorhandene Dateien gefiltertquelle
Verwenden Sie
os.path.join()
, um Ihre Pfade zu konstruieren - Es ist ordentlicher:quelle
os.walk
führt standardmäßig einen rekursiven Spaziergang durch. Ausgehend von root ergibt sich für jedes Verzeichnis ein 3-Tupel (dirpath, dirnames, filenames).quelle
walk()
Sie in Python 2.6 eine rekursive Liste zurück. Ich habe Ihren Code ausprobiert und eine Liste mit vielen Wiederholungen erhalten ... Wenn Sie nur Zeilen unter dem Kommentar "# rekursive Aufrufe von Unterordnern" entfernen - es funktioniert gutVersuche dies:
quelle
Ich denke, das Problem ist, dass Sie die Ausgabe von nicht
os.walk
richtig verarbeiten.Ändern Sie zunächst:
zu:
rootdir
ist Ihr festes Startverzeichnis;root
ist ein Verzeichnis, das von zurückgegeben wirdos.walk
.Zweitens müssen Sie Ihre Dateiverarbeitungsschleife nicht einrücken, da es keinen Sinn macht, diese für jedes Unterverzeichnis auszuführen. Sie werden
root
auf jedes Unterverzeichnis eingestellt. Sie müssen die Unterverzeichnisse nicht manuell verarbeiten, es sei denn, Sie möchten etwas mit den Verzeichnissen selbst tun.quelle
filePath = rootdir + '/' + file
, das klingt nicht richtig: Datei ist aus der Liste der aktuellen Dateien, also schreiben Sie in viele vorhandene Dateien?