J'ai une formation en C ++ / Obj-C et je découvre juste Python (je l'écris depuis environ une heure). J'écris un script pour lire récursivement le contenu des fichiers texte dans une structure de dossiers.
Le problème que j'ai est que le code que j'ai écrit ne fonctionnera que pour un dossier en profondeur. Je peux voir pourquoi dans le code (voir #hardcoded path
), je ne sais tout simplement pas comment je peux aller de l'avant avec Python car mon expérience avec celui-ci n'est que toute nouvelle.
Code Python:
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
n'est pas mauvais, même si j'ai trouvé un moyen encore plus rapide viaos.scandir
. Toutes lesglob
solutions sont beaucoup plus lentes quewalk
&scandir
. Ma fonction, ainsi qu'une analyse complète de la vitesse, peuvent être trouvées ici: stackoverflow.com/a/59803793/2441026Si vous utilisez Python 3.5 ou supérieur, vous pouvez le faire en 1 ligne.
Comme mentionné dans la documentation
Si vous voulez chaque fichier, vous pouvez utiliser
la source
root_dir
besoin d'une barre oblique finale? Cela fera gagner du temps aux gens (ou du moins cela m'aurait fait gagner du temps). Merci.glob.iglob(root_dir + '**/**', recursive=True)
. Je travaille en Python 3.8.2D'accord avec Dave Webb,
os.walk
produira un élément pour chaque répertoire de l'arborescence. Le fait est que vous n'avez pas à vous souciersubFolders
.Un code comme celui-ci devrait fonctionner:
la source
TL; DR: C'est l'équivalent de
find -type f
parcourir tous les fichiers dans tous les dossiers ci-dessous et y compris celui en cours:Comme déjà mentionné dans d'autres réponses,
os.walk()
c'est la réponse, mais elle pourrait être mieux expliquée. C'est assez simple! Parcourons cet arbre:Avec ce code:
C'est
currentpath
le dossier actuel qu'il regarde. Cela produira:Il boucle donc trois fois, car il existe trois dossiers: le dossier actuel,,
docs
etpics
. Dans chaque boucle, il remplit les variablesfolders
etfiles
avec tous les dossiers et fichiers. Montrons-leur:Cela nous montre:
Donc, dans la première ligne, nous voyons que nous sommes dans un dossier
.
, qu'il contient deux dossiers à savoirpics
etdocs
, et qu'il y a un fichier, à savoirtodo.txt
. Vous n'avez rien à faire pour récursivement dans ces dossiers, car comme vous le voyez, il se reproduit automatiquement et vous donne simplement les fichiers dans tous les sous-dossiers. Et tous les sous-dossiers de cela (bien que nous n'en ayons pas dans l'exemple).Si vous voulez simplement parcourir tous les fichiers, l'équivalent de
find -type f
, vous pouvez le faire:Cela produit:
la source
La
pathlib
bibliothèque est vraiment idéale pour travailler avec des fichiers. Vous pouvez faire un glob récursif sur unPath
objet comme ça.la source
Si vous voulez une liste plate de tous les chemins sous un répertoire donné (comme
find .
dans le shell):Pour inclure uniquement les chemins d'accès complets aux fichiers sous le répertoire de base, omettez
+ subdirs
.la source
**/**
est utilisé pour obtenir récursivement tous les fichiers, y comprisdirectory
.if os.path.isfile(filename)
est utilisé pour vérifier si lafilename
variable estfile
oudirectory
, s'il s'agit d'un fichier, nous pouvons lire ce fichier. Ici, j'imprime un fichier.la source
J'ai trouvé que ce qui suit était le plus simple
L'utilisation
glob('some/path/**', recursive=True)
obtient tous les fichiers, mais inclut également les noms de répertoire. L'ajout de laif os.path.isfile(f)
condition filtre cette liste aux fichiers existants uniquementla source
utiliser
os.path.join()
pour construire vos chemins - C'est plus soigné:la source
os.walk
fait une marche récursive par défaut. Pour chaque répertoire, à partir de la racine, il donne un triplet (répertoire, répertoires, noms de fichiers)la source
walk()
do retour liste récursive. J'ai essayé votre code et j'ai obtenu une liste avec de nombreuses répétitions ... Si vous supprimez simplement les lignes sous le commentaire "# appels récursifs sur les sous-dossiers" - cela fonctionne très bienEssaye ça:
la source
Je pense que le problème est que vous ne traitez pas
os.walk
correctement la sortie de .Tout d'abord, changez:
à:
rootdir
est votre répertoire de départ fixe;root
est un répertoire renvoyé paros.walk
.Deuxièmement, vous n'avez pas besoin de mettre en retrait votre boucle de traitement de fichiers, car cela n'a aucun sens de l'exécuter pour chaque sous-répertoire. Vous serez
root
configuré pour chaque sous-répertoire. Vous n'avez pas besoin de traiter les sous-répertoires à la main, sauf si vous voulez faire quelque chose avec les répertoires eux-mêmes.la source
filePath = rootdir + '/' + file
, cela ne semble pas correct: le fichier provient de la liste des fichiers actuels, vous écrivez donc sur un grand nombre de fichiers existants?