web-dev-qa-db-fra.com

os.walk sans dossiers cachés

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.

Cependant, il répertorie également les dossiers et fichiers cachés. J'aimerais que mon application ne répertorie aucun dossier ou fichier caché. Y a-t-il un indicateur que vous pouvez utiliser pour qu'il ne génère aucun fichier caché?

La multiplateforme n'est pas vraiment importante pour moi, c'est ok si cela ne fonctionne que pour linux (modèle. *)

36
lolopop

Non, il n'y a pas d'option pour os.walk() qui les sautera. Vous devrez le faire vous-même (ce qui est assez simple):

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 de tranche dirs[:] =; os.walk Parcourt récursivement les sous-répertoires répertoriés dans dirs. En remplaçant les éléments de dirs par ceux qui satisfont à un critère (par exemple, les répertoires dont les noms ne commencent pas par .), os.walk() ne visitera pas les répertoires qui ne répondent pas aux critères.

Cela ne fonctionne que si vous conservez l'argument de mot clé topdown dans True, à partir de documentation de os.walk() :

Lorsque topdown est True, l'appelant peut modifier la liste des noms de répertoire sur place (peut-être en utilisant del ou l'affectation de tranche), et walk() ne fera que récuser dans les sous-répertoires dont les noms restent dans dirnames ; 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().

84
Martijn Pieters

Je me rends compte que cela n'a pas été demandé dans la question, mais j'ai eu un problème similaire où je voulais exclure les fichiers cachés et les fichiers commençant par __, Plus précisément __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 noms de répertoires comme suit:

    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)]
10
dmmfll

Mon cas d'utilisation était similaire à celui de OP, sauf que je voulais retourner un décompte du nombre total de sous-répertoires dans un certain dossier. Dans mon cas, je voulais omettre tous les sous-répertoires nommés .git (ainsi que tous les dossiers pouvant être imbriqués dans ces .git Dossiers).

Dans Python 3.6.7, j'ai trouvé que l'approche de la réponse acceptée ne fonctionnait pas - elle comptait tout .git dossier et leurs sous-dossiers. Voici ce qui a fonctionné pour moi:

num_local_subdir = 0
for root, dirs, files in os.walk(local_folder_path):
    if '.git' in dirs:
        dirs.remove('.git')
    num_local_subdir += (len(dirs))
0
James Dellinger