226 votes

Liste Python des répertoires, sous-répertoires et fichiers

J'essaie de créer un script pour lister 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, il ne fonctionne pas correctement.
J'obtiens tous les fichiers, mais pas leur chemin d'accès complet.

Par exemple, si la structure du répertoire est la suivante

/home/patate/directory/targetdirectory/123/456/789/file.txt

Il s'imprime :

/home/patate/directory/targetdirectory/file.txt

Ce dont j'ai besoin, c'est du premier résultat. Toute aide serait grandement appréciée ! Je vous remercie.

370voto

Eli Bendersky Points 82298

Utilisation os.path.join pour concaténer les répertoire et le dossier 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, puisque l'utilisation de root serait incorrect.


Dans Python 3.4, l'option pathlib a été ajouté pour faciliter la manipulation des chemins. Ainsi, l'équivalent de os.path.join serait :

pathlib.PurePath(path, name)

L'avantage de pathlib est que vous pouvez utiliser une variété de méthodes utiles sur les chemins. Si vous utilisez la méthode concrète Path variante : vous pouvez également effectuer des appels au système d'exploitation par leur intermédiaire, comme changer de répertoire, supprimer le chemin d'accès, ouvrir le fichier vers lequel il pointe, etc.

76voto

Ivan Points 401

Au cas où... Récupérer tous les fichiers du répertoire et des sous-répertoires correspondant à un certain motif (*.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))

34voto

Mong H. Ng Points 426

Je n'ai pas pu commenter et j'écris donc ma 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]

13voto

ThorSummoner Points 396

En voici un exemple :

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 partie la plus extérieure val for sublist in ... aplatit la liste pour la rendre unidimensionnelle. La boucle j recueille une liste de tous les noms de base des fichiers et les joint au chemin d'accès actuel. Enfin, la boucle i itère sur tous les répertoires et sous-répertoires.

Cet exemple utilise le chemin codé en dur ./ dans le os.walk(...) vous pouvez ajouter n'importe quelle chaîne de chemin d'accès.

Nota: os.path.expanduser et/ou os.path.expandvars peut être utilisé pour les chaînes de chemins comme ~/

Prolongation de cet exemple :

Il est facile d'ajouter des tests de nom de base de fichier et des tests de nom de répertoire.

Par exemple, les tests de *.jpg des dossiers :

... for j in i[2] if j.endswith('.jpg')] ...

En outre, si l'on exclut les .git répertoire :

... for i in os.walk('./') if '.git' not in i[0].split('/')]

8voto

leOm Points 20

Une autre option consisterait à utiliser la fonction glob de la bibliothèque standard :

import glob

path = "/home/patate/directory/targetdirectory/**"

for path in glob.glob(path, recursive=True):
    print(path)

Si vous avez besoin d'un itérateur, vous pouvez utiliser iglob comme alternative :

for file in glob.iglob(my_path, recursive=True):
    # ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X