Python glob несколько типов файлов



есть ли лучший способ использовать glob.glob в python, чтобы получить список из нескольких типов файлов, таких как .формат txt. ,mdown все, а .уценка? Прямо сейчас у меня есть что-то вроде этого:



projectFiles1 = glob.glob( os.path.join(projectDir, '*.txt') )
projectFiles2 = glob.glob( os.path.join(projectDir, '*.mdown') )
projectFiles3 = glob.glob( os.path.join(projectDir, '*.markdown') )
975   25  

25 ответов:

может быть, есть лучший способ, но как насчет:

>>> 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

возможно, есть другой способ, поэтому подождите, если кто-то другой придумает лучший ответ.

from glob import glob

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

print(files)

Если вам нужно указать путь, цикл по шаблонам соответствия и сохранить соединение внутри цикла для простоты:

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)

цепи результаты:

import itertools as it, glob

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

затем:

for filename in multiple_file_types("*.txt", "*.sql", "*.log"):
    # do stuff

glob возвращает список: почему бы просто не запустить его несколько раз и объединить результаты?

from glob import glob
ProjectFiles = glob('*.txt') + glob('*.mdown') + glob('*markdown')

С glob это невозможно. вы можете использовать только:
* соответствует все
? соответствует любому одиночному символу
[далее] соответствует любому символу в seq
[!сл] соответствует любому символу, не в seq

использовать ОС.listdir и регулярное выражение для проверки модели:

for x in os.listdir('.'):
  if re.match('.*\.txt|.*\.sql', x):
    print x

например,*.mp3 и *.flac на нескольких папках, вы можете сделать:

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

идея может быть расширена до большего количества расширений файлов,но вы должны проверить, что комбинации не будут соответствовать любому другому нежелательному расширению файла, которое вы можете иметь в этих папках. Итак,будьте осторожны С этим.

после того, как я пришел сюда за помощью, я сделал свое собственное решение и хотел поделиться им. Он основан на ответе user2363986, но я думаю, что это более масштабируемо. Это означает, что если у вас есть 1000 расширений, код все равно будет выглядеть несколько элегантно.

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

я выпустил Муравьиная который реализует несколько включает в себя аналогично Apache Ant в файлы и шаблоны.

поиск может быть реализован:

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

поскольку реализован полный Ant glob, вы можете включать разные каталоги с каждым шаблоном, поэтому вы можете выбрать только те .txt файлов в одном подкаталоге, а .уценка в другом, например:

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

Я надеюсь, что это помогает.

не glob, но вот еще один способ использования понимания списка:

extensions = 'txt mdown markdown'.split()
projectFiles = [f for f in os.listdir(projectDir) 
                  if os.path.splitext(f)[1][1:] in extensions]

следующая функция _glob глобусы для нескольких расширений файлов.

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")

вот однострочный список-вариант понимания ответа Пэта (который также включает в себя то, что вы хотели glob в определенном каталоге проекта):

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

вы перебираете расширения (for ext in exts), а затем для каждого расширения вы берете каждый файл, соответствующий шаблону glob (for f in glob.glob(os.path.join(project_dir, ext)).

данное решение короче, и без каких-либо ненужных для-циклов, вложенных списков или функций для загромождения кода. Просто чистый, выразительный, питонический Дзэн.

это решение позволяет вам иметь пользовательский список exts это может быть изменено без необходимости обновления кода. (Это всегда хорошая практика!)

список-понимание то же самое используется в решении Лорана (за которое я голосовал). Но я бы сказал, что обычно нет необходимости выделять одну строку в отдельную функцию, поэтому я предоставляю это в качестве альтернативы решение.

бонус:

Если вам нужно искать не только один каталог, но и все подкаталоги, вы можете пройти recursive=True и использовать мульти-каталог Глоб символ **1:

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

появится glob.glob('<project_dir>/**/*.txt', recursive=True) и так далее для каждого расширения.

1 технически ** символ глобуса просто соответствует одному или нескольким символам в том числе косая черта/ (в отличие от единственного числа * символ Глоб). На практике вам просто нужно помнить, что пока вы окружаете ** С прямыми косыми чертами (разделители пути), он соответствует нулю или более каталогов.

Это в Python 3.4+ pathlib устранение:

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("~"))

также он игнорирует все имена файлов, начиная с ~.

один лайнер, просто для ада..

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]

выход:

['C:\multi_pattern_glob_one_liner\dummy_txt.txt', 'C:\multi_pattern_glob_one_liner\dummy_bat.bat']

до glob несколько типов файлов, вам нужно позвонить glob() функции несколько раз в цикле. Поскольку эта функция возвращает список, необходимо объединить списки.

например, эта функция выполняет задание:

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

простое использование:

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

вы также можете использовать glob.iglob() иметь итератор:

возвращает итератор, который дает те же значения, что и glob (), фактически не сохраняя их все одновременно.

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'))

вы можете попробовать сделать ручной список, сравнивая расширение существующих с теми, которые вам нужны.

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)

вы можете использовать фильтр:

import os
import glob

projectFiles = filter(
    lambda x: os.path.splitext(x)[1] in [".txt", ".mdown", ".markdown"]
    glob.glob(os.path.join(projectDir, "*"))
)

вы также можете использовать reduce() вот так:

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

это создает список из glob.glob() для каждого шаблона и сводит их к одному списку.

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

один шар, много расширений... но несовершенное решение (может соответствовать другим файлам).

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)

У меня была такая же проблема и вот что я придумал

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))

например:

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']

функция:

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

используйте список расширений и повторите

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)

Это Должно Работать:

import glob
extensions = ('*.txt', '*.mdown', '*.markdown')
for i in extensions:
    for files in glob.glob(i):
        print (files)

это сработало для меня:

import glob
images = glob.glob('*.JPG' or '*.jpg' or '*.png')

Comments

    Ничего не найдено.