Je veux créer un programme qui utilise du code de base pour lire un dossier et me dire combien de fichiers se trouvent dans le dossier. Voici comment je fais cela actuellement:
import os
folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
for root, dirs, files in os.walk(stuff, topdown=True):
print("there are", len(files), "files in", root)
Cela fonctionne très bien jusqu'à ce qu'il y ait plusieurs dossiers à l'intérieur du dossier "principal" car il peut renvoyer une longue liste de fichiers indésirable en raison d'une mauvaise gestion des dossiers/fichiers. Je ne voudrais donc aller qu'au deuxième niveau tout au plus. exemple:
Main Folder
---file_i_want
---file_i_want
---Sub_Folder
------file_i_want <--*
------file_i want <--*
------Sub_Folder_2
---------file_i_dont_want
---------file_i_dont_want
Je sais comment aller uniquement au premier niveau avec un break
et avec del dirs[:]
extrait de cet article et également cet article .
import os
import pandas as pd
folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
for root, dirs, files in os.walk(stuff, topdown=True):
print("there are", len(files), "files in", root)
del dirs[:] # or a break here. does the same thing.
Mais peu importe ma recherche, je ne peux pas savoir comment aller en profondeur. Je ne comprends peut-être pas les autres messages ou quelque chose? Je pensais à quelque chose comme del dirs[:2]
mais en vain. Quelqu'un peut-il me guider ou m'expliquer comment y parvenir?
vous pourriez faire comme ça:
depth = 2
# [1] abspath() already acts as normpath() to remove trailing os.sep
#, and we need ensures trailing os.sep not exists to make slicing accurate.
# [2] abspath() also make /../ and ////, "." get resolved even though os.walk can returns it literally.
# [3] expanduser() expands ~
# [4] expandvars() expands $HOME
stuff = os.path.abspath(os.path.expanduser(os.path.expandvars(stuff)))
for root,dirs,files in os.walk(stuff):
if root[len(stuff):].count(os.sep) < depth:
for f in files:
print(os.path.join(root,f))
la clé est: if root[len(stuff):].count(os.sep) < depth
Il supprime stuff
de root
, donc le résultat est relatif à stuff
. Il suffit de compter le nombre de séparateurs de fichiers.
La profondeur agit comme la commande find
trouvée sous Linux, c'est-à-dire que -maxdepth 0
Signifie ne rien faire, -maxdepth 1
Ne scanne que les fichiers de premier niveau et -maxdepth 2
Scanne les fichiers inclus sous -annuaire.
Bien sûr, il analyse toujours la structure complète du fichier, mais à moins qu'il ne soit très profond, cela fonctionnera.
Une autre solution serait d'utiliser uniquement os.listdir
Récursivement (avec vérification du répertoire) avec un niveau de récursivité maximum, mais c'est un peu plus compliqué si vous n'en avez pas besoin. Comme ce n'est pas si difficile, voici une implémentation:
def scanrec(root):
rval = []
def do_scan(start_dir,output,depth=0):
for f in os.listdir(start_dir):
ff = os.path.join(start_dir,f)
if os.path.isdir(ff):
if depth<2:
do_scan(ff,output,depth+1)
else:
output.append(ff)
do_scan(root,rval,0)
return rval
print(scanrec(stuff)) # prints the list of files not below 2 deep
Remarque: os.listdir
Et os.path.isfile
Effectuent 2 stat
appels donc pas optimal. Dans Python 3.5, l'utilisation de os.scandir
Pourrait éviter ce double appel.
Vous pouvez compter les séparateurs et s'il s'agit de deux niveaux de profondeur, supprimez le contenu de dirs
afin que walk
ne récapitule pas plus profondément:
import os
MAX_DEPTH = 2
folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
for root, dirs, files in os.walk(stuff, topdown=True):
print("there are", len(files), "files in", root)
if root.count(os.sep) - stuff.count(os.sep) == MAX_DEPTH - 1:
del dirs[:]
documentation Python indique ce qui suit concernant le comportement:
Lorsque topdown a la valeur True, l'appelant peut modifier la liste des noms de répertoire sur place (peut-être en utilisant l'affectation del ou slice), et walk () ne récursera que dans les sous-répertoires dont les noms restent dans les noms de répertoire; cela peut être utilisé pour élaguer la recherche, imposer un ordre de visite spécifique ou même pour informer walk () des répertoires que l'appelant crée ou renomme avant de reprendre walk ().
Notez que vous devez prendre en compte les séparateurs présents dans le folders
. Par exemple, lorsque y:\path1
est parcouru root est y:\path
mais vous ne voulez pas arrêter la récursion ici.