2012-11-19 10 views
25

J'ai besoin de lister tous les fichiers avec le chemin du répertoire contenant dans un dossier. J'ai essayé d'utiliser os.walk, ce qui serait évidemment la solution parfaite.os.walk sans dossiers cachés

Cependant, il répertorie également les dossiers cachés et les fichiers. Je voudrais que mon application ne lise aucun dossier ou dossier caché. Y a-t-il un drapeau que vous pouvez utiliser pour le faire ne céder aucun fichier caché?

multi-plateforme est pas vraiment important pour moi, il est ok si elle ne fonctionne que pour linux (. * Motif)

+1

Quelle plate-forme êtes-vous? «caché» a des significations différentes sur différents systèmes d'exploitation. –

+0

Je suis sur Linux, je vais ajouter cela sur la réponse. – lolopop

Répondre

56

Non, il n'y a pas possibilité de os.walk() qui va sauter ceux-ci. Vous aurez besoin de le faire vous-même (ce qui est assez facile):

for root, dirs, files in os.walk(path): 
    files = [f for f in files if not f[0] == '.'] 
    dirs[:] = [d for d in dirs if not d[0] == '.'] 
    # use files and dirs 

Notez l'affectation des tranches dirs[:] =; nous remplaçons les éléments dans dirs (et non la liste référencée par dirs) afin que os.walk() ne traite pas les répertoires supprimés.

Cela ne fonctionne que si vous gardez l'argument mot-clé topdown-True, du documentation of os.walk():

Lorsque topdown est True, l'appelant peut modifier la liste des dirnames en place (peut-être à l'aide del ou affectation de tranche) et walk() ne se recurderont que dans les sous-répertoires dont les noms restent dans noms de serveur; cela peut être utilisé pour élaguer la recherche, imposer un ordre spécifique de visite, ou même informer walk() sur les répertoires que l'appelant crée ou renomme avant qu'il ne reprenne walk().

+0

Merci beaucoup, ne savais pas que vous pouvez modifier les listes en place! – lolopop

+0

J'ai couru cela mais il n'a rien imprimé sur la console. Quelle est la méthode typique pour afficher les fichiers trouvés de cette façon? J'ai ajouté 'print root, dirs, files' à la fin mais il est sorti très en désordre. – user5359531

+1

@ user5359531: cela dépend entièrement de votre utilisation; vous pouvez 'imprimer '\ n'.join ([os.path.join (root, f) pour f dans dirs + fichiers])', etc. –

5

Je me rends compte qu'il n'a pas été posée dans la question, mais j'eu un problème similaire où je voulais exclure les fichiers cachés et les fichiers commençant par __, en particulier __pycache__ répertoires. J'ai atterri sur cette question parce que j'essayais de comprendre pourquoi ma compréhension de la liste ne faisait pas ce que j'attendais. Je ne modifiais pas la liste en place avec dirnames[:].

J'ai créé une liste de préfixes que je voulais exclure et modifié les dirnames en place comme ceci:

exclude_prefixes = ('__', '.') # exclusion prefixes 
    for dirpath, dirnames, filenames in os.walk(node): 
     # exclude all dirs starting with exclude_prefixes 
     dirnames[:] = [dirname 
         for dirname in dirnames 
         if not dirname.startswith(exclude_prefixes)] 
+0

c'est une bonne réponse, fonctionne parfaitement pour l'exclusion selon une liste – jpwynn

+1

FYI, 'startswith' peut également prendre une suite de chaînes, donc vous pouvez vous débarrasser de la boucle interne et utiliser' pas dirname.startswith (exclude_prefixes) 'https://docs.python.org/2/library/stdtypes .html # str.startswith (python 2.5 et plus) –