J'essaie de créer un script pour répertorier tous les répertoires, sous-répertoires et fichiers d'un répertoire donné.
J'ai essayé ceci:
import sys,os
root = "/home/patate/directory/"
path = os.path.join(root, "targetdirectory")
for r,d,f in os.walk(path):
for file in f:
print os.path.join(root,file)
Malheureusement, cela ne fonctionne pas correctement.
Je récupère tous les fichiers, mais pas leur chemin complet.
Par exemple, si la structure dir est:
/home/patate/directory/targetdirectory/123/456/789/file.txt
Il imprimerait:
/home/patate/directory/targetdirectory/file.txt
Ce dont j'ai besoin, c'est le premier résultat. Toute aide serait grandement appréciée! Merci.
Utilisez os.path.join
pour concaténer le répertoire et le fichier nom:
for path, subdirs, files in os.walk(root):
for name in files:
print os.path.join(path, name)
Notez l'utilisation de path
et non root
dans la concaténation, car utiliser root
serait incorrect.
Dans Python 3.4, le module pathlib a été ajouté pour faciliter les manipulations de chemin. Donc l'équivalent de os.path.join
serait:
pathlib.PurePath(path, name)
L’avantage de pathlib
est que vous pouvez utiliser diverses méthodes utiles sur les chemins. Si vous utilisez la variante concrète Path
, vous pouvez également effectuer de véritables appels système, comme modifier un répertoire, supprimer le chemin, ouvrir le fichier indiqué, etc.
Juste au cas où ... Obtenir tous les fichiers du répertoire et des sous-répertoires correspondant à un modèle (* .py par exemple):
import os
from fnmatch import fnmatch
root = '/some/directory'
pattern = "*.py"
for path, subdirs, files in os.walk(root):
for name in files:
if fnmatch(name, pattern):
print os.path.join(path, name)
import os
[val for sublist in [[os.path.join(i[0], j) for j in i[2]] for i in os.walk('./')] for val in sublist]
# Meta comment to ease selecting text
La boucle la plus externe val for sublist in ...
aplatit la liste pour qu'elle soit unidimensionnelle. La boucle j
collecte une liste de chaque nom de base de fichier et la joint au chemin actuel. Enfin, la boucle i
parcourt tous les répertoires et sous-répertoires.
Cet exemple utilise le chemin d'accès codé en dur ./
dans l'appel os.walk(...)
, vous pouvez compléter n'importe quelle chaîne de chemin d'accès de votre choix.
Remarque: os.path.expanduser
et/ou os.path.expandvars
peut être utilisé pour les chaînes de chemin d'accès telles que ~/
Il est facile d’ajouter des tests de nom de fichier et de nom de répertoire.
Par exemple, testez les fichiers *.jpg
:
... for j in i[2] if j.endswith('.jpg')] ...
De plus, à l'exclusion du répertoire .git
:
... for i in os.walk('./') if '.git' not in i[0].split('/')]
Vous devriez utiliser 'r' dans votre jointure au lieu de 'root'
Je ne peux pas commenter, écrivez donc la réponse ici. C'est la ligne la plus claire que j'ai vue:
import os
[os.path.join(path, name) for path, subdirs, files in os.walk(root) for name in files]
Vous pouvez jeter un oeil à cet échantillon que j'ai fait. Il utilise la fonction os.path.walk qui est déconseillée. Attention. Utilise une liste pour stocker tous les chemins de fichiers.
root = "Your root directory"
ex = ".txt"
where_to = "Wherever you wanna write your file to"
def fileWalker(ext,dirname,names):
'''
checks files in names'''
pat = "*" + ext[0]
for f in names:
if fnmatch.fnmatch(f,pat):
ext[1].append(os.path.join(dirname,f))
def writeTo(fList):
with open(where_to,"w") as f:
for di_r in fList:
f.write(di_r + "\n")
if __== '__main__':
li = []
os.path.walk(root,fileWalker,[ex,li])
writeTo(li)
Un peu plus simple one-liner:
import os
from itertools import product, chain
chain.from_iterable([["\\".join(w) for w in product([i[0]], i[2])] for i in os.walk(dir)])
Étant donné que chaque exemple utilisé ici utilise uniquement walk
(avec join
), j'aimerais montrer un exemple intéressant et une comparaison avec listdir
:
import os, time
def listFiles1(root): # listdir
allFiles = []; walk = [root]
while walk:
folder = walk.pop(0)+"/"; items = os.listdir(folder) # items = folders + files
for i in items: i=folder+i; (walk if os.path.isdir(i) else allFiles).append(i)
return allFiles
def listFiles2(root): # listdir/join (takes ~1.4x as long) (and uses '\\' instead)
allFiles = []; walk = [root]
while walk:
folder = walk.pop(0); items = os.listdir(folder) # items = folders + files
for i in items: i=os.path.join(folder,i); (walk if os.path.isdir(i) else allFiles).append(i)
return allFiles
def listFiles3(root): # walk (takes ~1.5x as long)
allFiles = []
for folder, folders, files in os.walk(root):
for file in files: allFiles+=[folder.replace("\\","/")+"/"+file] # folder+"\\"+file still ~1.5x
return allFiles
def listFiles4(root): # walk/join (takes ~1.6x as long) (and uses '\\' instead)
allFiles = []
for folder, folders, files in os.walk(root):
for file in files: allFiles+=[os.path.join(folder,file)]
return allFiles
for i in range(100): files = listFiles1("src") # warm up
start = time.time()
for i in range(100): files = listFiles1("src") # listdir
print("Time taken: %.2fs"%(time.time()-start)) # 0.28s
start = time.time()
for i in range(100): files = listFiles2("src") # listdir and join
print("Time taken: %.2fs"%(time.time()-start)) # 0.38s
start = time.time()
for i in range(100): files = listFiles3("src") # walk
print("Time taken: %.2fs"%(time.time()-start)) # 0.42s
start = time.time()
for i in range(100): files = listFiles4("src") # walk and join
print("Time taken: %.2fs"%(time.time()-start)) # 0.47s
Comme vous pouvez le constater, la version listdir
est beaucoup plus efficace. (et que join
est lent)