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') )
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.
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)
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
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')
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
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.
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
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.
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]
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")
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.
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 ~
.
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']
à 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)))
files = glob.glob('*.txt')
files.extend(glob.glob('*.dat'))
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)
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, "*"))
)
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.
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
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)
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))
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
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)
Cela Devrait Fonctionner:
import glob
extensions = ('*.txt', '*.mdown', '*.markdown')
for i in extensions:
for files in glob.glob(i):
print (files)
cela a fonctionné pour moi:
import glob
images = glob.glob('*.JPG' or '*.jpg' or '*.png')