Python glob plusieurs types de fichiers

Est-il une meilleure façon d'utiliser glob.glob en python pour obtenir une liste de plusieurs types de fichier comme .txt,.madown, and .démarques? Maintenant j'ai quelque chose comme ceci:

projectFiles1 = glob.glob( os.path.join(projectDir, '*.txt') )
projectFiles2 = glob.glob( os.path.join(projectDir, '*.mdown') )
projectFiles3 = glob.glob( os.path.join(projectDir, '*.markdown') )
79
demandé sur Raptrex 2010-12-31 09:39:15

25 réponses

peut-être qu'il y a un meilleur moyen, mais qu'en est-il:

>>> import glob
>>> types = ('*.pdf', '*.cpp') # the tuple of file types
>>> files_grabbed = []
>>> for files in types:
...     files_grabbed.extend(glob.glob(files))
... 
>>> files_grabbed   # the list of pdf and cpp files

il y a peut-être un autre moyen, alors attendez au cas où quelqu'un d'autre aurait une meilleure réponse.

89
répondu user225312 2012-07-22 16:32:38
from glob import glob

files = glob('*.gif')
files.extend(glob('*.png'))
files.extend(glob('*.jpg'))

print(files)

si vous avez besoin de spécifier un chemin, boucle sur les modèles de correspondance et garder la jointure à l'intérieur de la boucle pour la simplicité:

from os.path import join
from glob import glob

files = []
for ext in ('*.gif', '*.png', '*.jpg'):
   files.extend(glob(join("path/to/dir", ext)))

print(files)
28
répondu user2363986 2015-12-26 18:15:12

enchaîner les résultats:

import itertools as it, glob

def multiple_file_types(*patterns):
    return it.chain.from_iterable(glob.iglob(pattern) for pattern in patterns)

puis:

for filename in multiple_file_types("*.txt", "*.sql", "*.log"):
    # do stuff
28
répondu tzot 2017-04-03 16:55:08

glob renvoie une liste: pourquoi ne pas l'exécuter plusieurs fois et concaténer les résultats?

from glob import glob
ProjectFiles = glob('*.txt') + glob('*.mdown') + glob('*markdown')
18
répondu patrick-mooney 2015-12-29 08:31:03

avec glob il n'est pas possible. vous pouvez utiliser seulement:

* correspond à tout

? correspond à un seul caractère

[seq] correspond à tout caractère dans seq

[!SEQ] correspond à tout caractère non en seq

utiliser os.listdir et un regexp pour vérifier les motifs:

for x in os.listdir('.'):
  if re.match('.*\.txt|.*\.sql', x):
    print x
13
répondu Christian 2010-12-31 07:07:23

par exemple, pour *.mp3 et *.flac sur plusieurs dossiers, vous pouvez faire:

mask = r'music/*/*.[mf][pl][3a]*'
glob.glob(mask)

l'idée peut être étendue à plus d'extensions de fichiers, mais vous devez vérifier que les combinaisons ne correspondent à aucune autre extension de fichier indésirable que vous pouvez avoir sur ces dossiers. Donc, soyez prudent avec ceci.

4
répondu feqwix 2016-03-22 23:11:25

après être venu ici pour de l'aide, j'ai fait ma propre solution et j'ai voulu la partager. C'est basé sur la réponse de l'user2363986, mais je pense que c'est plus évolutif. Ce qui signifie que si vous avez 1000 extensions, le code sera encore élégant.

from glob import glob

directoryPath  = "C:\temp\*." 
fileExtensions = [ "jpg", "jpeg", "png", "bmp", "gif" ]
listOfFiles    = []

for extension in fileExtensions:
    listOfFiles.extend( glob( directoryPath + extension ))

for file in listOfFiles:
    print(file)   # Or do other stuff
3
répondu Hans Goldman 2017-06-16 16:42:46

j'ai publié Formique , qui met en œuvre de multiples comprend une manière similaire à Apache Ant FileSet et Globs .

la recherche peut être implémentée:

import formic
patterns = ["*.txt", "*.markdown", "*.mdown"]
fileset = formic.FileSet(directory=projectDir, include=patterns)
for file_name in fileset.qualified_files():
    # Do something with file_name

parce que le Full ANT glob est implémenté, vous pouvez inclure différents répertoires avec chaque motif, donc vous pouvez choisir seulement ceux-là .les fichiers txt dans un sous-répertoire, et le .markdown dans un autre, par exemple:

patterns = [ "/unformatted/**/*.txt", "/formatted/**/*.mdown" ]

j'espère que cela aidera.

2
répondu Andrew Alcock 2012-05-15 09:30:12

pas glob , Mais voici une autre façon d'utiliser une liste de compréhension:

extensions = 'txt mdown markdown'.split()
projectFiles = [f for f in os.listdir(projectDir) 
                  if os.path.splitext(f)[1][1:] in extensions]
2
répondu joemaller 2012-12-06 03:36:52

La fonction suivante _glob globs pour plusieurs extensions de fichier.

import glob
import os
def _glob(path, *exts):
    """Glob for multiple file extensions

    Parameters
    ----------
    path : str
        A file name without extension, or directory name
    exts : tuple
        File extensions to glob for

    Returns
    -------
    files : list
        list of files matching extensions in exts in path

    """
    path = os.path.join(path, "*") if os.path.isdir(path) else path + "*"
    return [f for files in [glob.glob(path + ext) for ext in exts] for f in files]

files = _glob(projectDir, ".txt", ".mdown", ".markdown")
2
répondu Tim Fuller 2013-01-15 15:34:38

Voici une liste en une ligne-variante de compréhension de la réponse de Pat (qui inclut également que vous vouliez glob dans un répertoire de projet spécifique):

import os, glob
exts = ['*.txt', '*.mdown', '*.markdown']
files = [f for ext in exts for f in glob.glob(os.path.join(project_dir, ext))]

vous bouclez les extensions ( for ext in exts ), puis pour chaque extension vous prenez chaque fichier correspondant au motif glob ( for f in glob.glob(os.path.join(project_dir, ext) ).

Cette solution est court , et sans aucune inutiles pour des boucles imbriquées liste des compréhensions, des fonctions ou à l'encombrement du code. Juste pur, expressif, pythonic Zen .

cette solution vous permet d'avoir une liste personnalisée de exts qui peut être modifié sans avoir à mettre à jour votre code. (Ce qui est toujours une bonne pratique!)

la liste-compréhension est la même que celle utilisée dans la solution de Laurent (pour laquelle J'ai voté). Mais je dirais qu'il est généralement inutile de factoriser une seule ligne à une autre fonction, qui est pourquoi Je suis de fournir cela comme une solution alternative.

Bonus:

si vous avez besoin de rechercher non seulement un répertoire unique, mais aussi tous les sous-répertoires, vous pouvez passer recursive=True et utiliser le symbole glob multi-répertoires ** 1 :

files = [f for ext in exts 
         for f in glob.glob(os.path.join(project_dir, '**', ext), recursive=True)]

cela invoquera glob.glob('<project_dir>/**/*.txt', recursive=True) et ainsi de suite pour chaque extension.

1 Techniquement, le symbole de glob ** correspond simplement à un ou plusieurs caractères incluant la barre oblique avant / (contrairement au symbole de glob au singulier * ). En pratique, vous devez juste vous rappeler que tant que vous entourez ** de slashs (séparateurs de chemin), il correspond à zéro ou plus de répertoires.

2
répondu scholer 2018-05-09 17:50:40

C'est un Python 3.4+ pathlib solution:

exts = ".pdf", ".doc", ".xls", ".csv", ".ppt"
filelist = (str(i) for i in map(pathlib.Path, os.listdir(src)) if i.suffix.lower() in exts and not i.stem.startswith("~"))

aussi, il ignore tous les noms de fichiers commençant par ~ .

1
répondu Winand 2015-10-09 07:42:54

une doublure, juste pour le diable..

folder = "C:\multi_pattern_glob_one_liner"
files = [item for sublist in [glob.glob(folder + ext) for ext in ["/*.txt", "/*.bat"]] for item in sublist]

sortie:

['C:\multi_pattern_glob_one_liner\dummy_txt.txt', 'C:\multi_pattern_glob_one_liner\dummy_bat.bat']
1
répondu Gil-Mor 2017-07-22 15:07:50

à glob types de fichiers multiples, vous devez appeler glob() fonction plusieurs fois dans une boucle. Puisque cette fonction renvoie une liste, vous devez concaténer les listes.

par exemple, cette fonction faire le travail:

import glob
import os


def glob_filetypes(root_dir, *patterns):
    return [path
            for pattern in patterns
            for path in glob.glob(os.path.join(root_dir, pattern))]

usage Simple:

project_dir = "path/to/project/dir"
for path in sorted(glob_filetypes(project_dir, '*.txt', '*.mdown', '*.markdown')):
    print(path)

vous pouvez également utiliser glob.iglob() pour avoir un itérateur:

renvoie un itérateur qui fournit les mêmes valeurs que glob() sans les stocker simultanément.

def iglob_filetypes(root_dir, *patterns):
    return (path
            for pattern in patterns
            for path in glob.iglob(os.path.join(root_dir, pattern)))
1
répondu Laurent LAPORTE 2017-09-13 13:08:17
files = glob.glob('*.txt')
files.extend(glob.glob('*.dat'))
1
répondu Derek White 2018-06-12 17:34:30

vous pouvez essayer de faire une liste manuelle comparant l'extension d'existant avec ceux que vous avez besoin.

ext_list = ['gif','jpg','jpeg','png'];
file_list = []
for file in glob.glob('*.*'):
  if file.rsplit('.',1)[1] in ext_list :
    file_list.append(file)
0
répondu thegauraw 2012-10-29 02:33:28

vous pouvez utiliser un filtre:

import os
import glob

projectFiles = filter(
    lambda x: os.path.splitext(x)[1] in [".txt", ".mdown", ".markdown"]
    glob.glob(os.path.join(projectDir, "*"))
)
0
répondu LK__ 2015-05-28 21:12:03

vous pouvez également utiliser reduce() comme suit:

import glob
file_types = ['*.txt', '*.mdown', '*.markdown']
project_files = reduce(lambda list1, list2: list1 + list2, (glob.glob(t) for t in file_types))

crée une liste à partir de glob.glob() pour chaque motif et les réduit à une seule liste.

0
répondu cyht 2016-11-07 19:35:28
import os    
import glob
import operator
from functools import reduce

types = ('*.jpg', '*.png', '*.jpeg')
lazy_paths = (glob.glob(os.path.join('my_path', t)) for t in types)
paths = reduce(operator.add, lazy_paths, [])

https://docs.python.org/3.5/library/functools.html#functools.reduce https://docs.python.org/3.5/library/operator.html#operator.add

0
répondu unpangloss 2017-04-24 04:27:40

un glob, plusieurs extensions... mais Solution imparfaite (pourrait correspondre à d'autres fichiers).

filetypes = ['tif', 'jpg']

filetypes = zip(*[list(ft) for ft in filetypes])
filetypes = ["".join(ch) for ch in filetypes]
filetypes = ["[%s]" % ch for ch in filetypes]
filetypes = "".join(filetypes) + "*"
print(filetypes)
# => [tj][ip][fg]*

glob.glob("/path/to/*.%s" % filetypes)
0
répondu colllin 2017-10-11 21:03:06

j'ai eu le même problème et c'est ce que j'ai trouvé

import os, sys, re

#without glob

src_dir = '/mnt/mypics/'
src_pics = []
ext = re.compile('.*\.(|{}|)$'.format('|'.join(['png', 'jpeg', 'jpg']).encode('utf-8')))
for root, dirnames, filenames in os.walk(src_dir):
  for filename in filter(lambda name:ext.search(name),filenames):
    src_pics.append(os.path.join(root, filename))
0
répondu Justin 2018-05-08 13:17:13

par exemple:

import glob
lst_img = []
base_dir = '/home/xy/img/'

# get all the jpg file in base_dir 
lst_img += glob.glob(base_dir + '*.jpg')
print lst_img
# ['/home/xy/img/2.jpg', '/home/xy/img/1.jpg']

# append all the png file in base_dir to lst_img
lst_img += glob.glob(base_dir + '*.png')
print lst_img
# ['/home/xy/img/2.jpg', '/home/xy/img/1.jpg', '/home/xy/img/3.png']

a fonction:

import glob
def get_files(base_dir='/home/xy/img/', lst_extension=['*.jpg', '*.png']):
    """
    :param base_dir:base directory
    :param lst_extension:lst_extension: list like ['*.jpg', '*.png', ...]
    :return:file lists like ['/home/xy/img/2.jpg','/home/xy/img/3.png']
    """
    lst_files = []
    for ext in lst_extension:
        lst_files += glob.glob(base_dir+ext)
    return lst_files
0
répondu Jayhello 2018-07-26 11:41:27

utiliser une liste d'extension et itérer jusqu'à

from os.path import join
from glob import glob

files = ['*.gif', '*.png', '*.jpg']
for ext in files:
   files.extend(glob(join("path/to/dir", ext)))

print(files)
0
répondu Projesh Bhoumik 2018-07-26 11:46:15

Cela Devrait Fonctionner:

import glob
extensions = ('*.txt', '*.mdown', '*.markdown')
for i in extensions:
    for files in glob.glob(i):
        print (files)
-1
répondu jdnoon 2014-11-05 12:45:14

cela a fonctionné pour moi:

import glob
images = glob.glob('*.JPG' or '*.jpg' or '*.png')
-1
répondu Sarvagya Gupta 2018-04-20 15:44:50