Comment ignorer les fichiers cachés en utilisant os.listdir ()?


87

Mon script python exécute un os.listdir(path)où le chemin est une file d'attente contenant des archives que je dois traiter une par une.

Le problème est que j'obtiens la liste dans un tableau et que je fais juste un simple array.pop(0). Cela fonctionnait bien jusqu'à ce que je mette le projet en subversion. Maintenant, je reçois le .svndossier dans mon tableau et bien sûr cela fait planter mon application.

Alors, voici ma question: y a-t-il une fonction qui ignore les fichiers cachés lors de l'exécution d'un os.listdir()et sinon quel serait le meilleur moyen?

Réponses:


102

Vous pouvez en écrire un vous-même:

def listdir_nohidden(path):
    for f in os.listdir(path):
        if not f.startswith('.'):
            yield f

Ou vous pouvez utiliser un glob :

def listdir_nohidden(path):
    return glob.glob(os.path.join(path, '*'))

L'un ou l'autre ignorera tous les noms de fichiers commençant par '.'.


1
la fonction proposée listdir_nohiddenn'est pas tout à fait compatible avec os.listdir, car l'utilisation de en yieldfait un générateur. Au lieu de cela, il doit parcourir la liste de sortie os.listdiret supprimer les entrées commençant par «.»
Milo Wielondek

3
@ 0sh: Pourquoi doit-il supprimer des éléments sur place? Définissez simplement une nouvelle fonction qui le fait list(listdir_nohidden(path))et avec laquelle cette nouvelle fonction est exactement compatible os.listdir.
abarnert

47

C'est une vieille question, mais il semble qu'il manque la réponse évidente de l'utilisation de la compréhension de liste, donc je l'ajoute ici pour être complète:

[f for f in os.listdir(path) if not f.startswith('.')]

En remarque, l'état des documents listdirrenverra les résultats dans un «ordre arbitraire», mais un cas d'utilisation courant consiste à les classer par ordre alphabétique. Si vous voulez que le contenu du répertoire soit trié par ordre alphabétique sans tenir compte des majuscules, vous pouvez utiliser:

sorted([f for f in os.listdir('./')], key=lambda f: f.lower())

5
key=lambda f: f.lower()peut s'écrire sans lambda:key=str.lower
Jean-François Fabre

2
Pour combiner les deux:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Robert

18

Sous Windows, Linux et OS X:

if os.name == 'nt':
    import win32api, win32con


def folder_is_hidden(p):
    if os.name== 'nt':
        attribute = win32api.GetFileAttributes(p)
        return attribute & (win32con.FILE_ATTRIBUTE_HIDDEN | win32con.FILE_ATTRIBUTE_SYSTEM)
    else:
        return p.startswith('.') #linux-osx

2
devrait également fonctionner sur un Mac, les fichiers cachés commencent par «.» ainsi que.
Verena Haunschmid

2
C'est la seule réponse portable, excellent travail, mais les autres réponses fournissent un wrapper complet pour os.listdir donc ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith


14

glob :

>>> import glob
>>> glob.glob('*')

( globprétend utiliser listdiret fnmatchsous le capot, mais il vérifie également un début '.', pas en utilisant fnmatch.)


6

Je pense que c'est trop de travail de parcourir tous les éléments en boucle. Je préférerais quelque chose de plus simple comme ceci:

lst = os.listdir(path)
if '.DS_Store' in lst:
    lst.remove('.DS_Store')

Si le répertoire contient plusieurs fichiers cachés , cela peut aider:

all_files = os.popen('ls -1').read()
lst = all_files.split('\n')

pour l'indépendance de la plate-forme comme @Josh l'a mentionné, le glob fonctionne bien:

import glob
glob.glob('*')

Cela ne fonctionne que si vous avez un fichier caché et que vous en connaissez le nom. Que faire si le répertoire contient des dizaines de fichiers cachés, avec des noms arbitraires que vous ne pouvez pas connaître à l'avance?
FeRD

Salut @FeRD, Oui. Lorsque je fais un traitement par lots / backlog sur un mac, je mets tous les fichiers dans un nouveau dossier et je suis .DS_Storecréé automatiquement. Lorsque je compresser tous les fichiers et les envoyer sur un serveur, je les .DS_Storeajoute également. S'il y a plusieurs fichiers cachés, vous pouvez peut-être essayeros.system('ls -1')
utilisateur 923227

Pas multi-plateforme. os.popen('ls -1').read()ne fonctionnera pas sous Windows. C'est tout l'intérêt de os.listdir().
FeRD

1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.