150 votes

Comment puis-je rechercher des sous-dossiers à l'aide du module glob.glob ?

Je veux ouvrir une série de sous-dossiers dans un dossier et trouver certains fichiers texte et imprimer certaines lignes des fichiers texte. J'utilise ceci :

configfiles = glob.glob('C:/Users/sam/Desktop/file1/*.txt')

Mais il ne peut pas non plus accéder aux sous-dossiers. Quelqu'un sait-il comment je peux utiliser la même commande pour accéder aux sous-dossiers ?

223voto

Martijn Pieters Points 271458

Dans Python 3.5 et les versions plus récentes, utilisez la nouvelle fonction récursive **/ fonctionnalité :

configfiles = glob.glob('C:/Users/sam/Desktop/file1/**/*.txt', recursive=True)

Quand recursive est réglé, ** suivi d'un séparateur de chemin correspond à 0 ou plusieurs sous-répertoires.

Dans les versions antérieures de Python, glob.glob() ne peut pas lister les fichiers dans les sous-répertoires de manière récursive.

Dans ce cas, j'utiliserais os.walk() combiné avec fnmatch.filter() à la place :

import os
import fnmatch

path = 'C:/Users/sam/Desktop/file1'

configfiles = [os.path.join(dirpath, f)
    for dirpath, dirnames, files in os.walk(path)
    for f in fnmatch.filter(files, '*.txt')]

Cela parcourra vos répertoires de manière récursive et renverra tous les noms de chemin absolus vers les correspondances. .txt des fichiers. Dans ce spécifique cas le fnmatch.filter() peut s'avérer excessif, vous pourriez également utiliser une .endswith() test :

import os

path = 'C:/Users/sam/Desktop/file1'

configfiles = [os.path.join(dirpath, f)
    for dirpath, dirnames, files in os.walk(path)
    for f in files if f.endswith('.txt')]

67voto

germ Points 121

Il y a beaucoup de confusion sur ce sujet. Laissez-moi voir si je peux le clarifier (Python 3.7) :

  1. glob.glob('*.txt') : correspond à tous les fichiers se terminant par '.txt' dans le répertoire actuel
  2. glob.glob('*/*.txt') : même que 1
  3. glob.glob('**/*.txt') : correspond à tous les fichiers se terminant par ".txt" dans le répertoire de l'utilisateur. uniquement les sous-répertoires immédiats mais pas dans le répertoire courant
  4. glob.glob('*.txt',recursive=True) : même que 1
  5. glob.glob('*/*.txt',recursive=True) : même que 3
  6. glob.glob('**/*.txt',recursive=True): correspond à tous les fichiers se terminant par '.txt' dans le répertoire actuel et dans tous les sous-répertoires

Il est donc préférable de toujours préciser recursive=True.

26voto

J.F. Sebastian Points 102961

Pour trouver les fichiers dans les sous-répertoires immédiats :

configfiles = glob.glob(r'C:\Users\sam\Desktop\*\*.txt')

Pour une version récursive qui traverse tous les sous-répertoires, vous pourriez utiliser ** et passer recursive=True depuis Python 3.5 :

configfiles = glob.glob(r'C:\Users\sam\Desktop\**\*.txt', recursive=True)

Les deux appels de fonction renvoient des listes. Vous pouvez utiliser glob.iglob() pour retourner les chemins un par un. Ou bien utiliser pathlib :

from pathlib import Path

path = Path(r'C:\Users\sam\Desktop')
txt_files_only_subdirs = path.glob('*/*.txt')
txt_files_all_recursively = path.rglob('*.txt') # including the current dir

Les deux méthodes renvoient des itérateurs (vous pouvez obtenir les chemins un par un).

17voto

megawac Points 3093

Le site glob2 supporte les jokers et est raisonnablement rapide

code = '''
import glob2
glob2.glob("files/*/**")
'''
timeit.timeit(code, number=1)

Sur mon ordinateur portable, la correspondance prend environ 2 secondes. >60 000 chemins de fichiers .

9voto

Andrew Alcock Points 10536

Vous pouvez utiliser Formic avec Python 2.6

import formic
fileset = formic.FileSet(include="**/*.txt", directory="C:/Users/sam/Desktop/")

Divulgation - Je suis l'auteur de ce paquet.

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