파이썬은 여러 파일 형식을 가져옵니다


142

python에서 glob.glob를 사용하여 .txt, .mdown 및 .markdown과 같은 여러 파일 유형 목록을 얻는 더 좋은 방법이 있습니까? 지금 나는 이와 같은 것을 가지고있다 :

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

답변:


156

더 좋은 방법이 있지만 어떻습니까?

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

# files_grabbed is the list of pdf and cpp files

다른 방법이있을 수 있으므로 다른 사람이 더 나은 답변을 얻을 수 있도록 기다립니다.


19
files_grabbed = [glob.glob(e) for e in ['*.pdf', '*.cpp']]
Novitoll

10
Novitoll의 솔루션은 짧지 만 중첩 목록을 생성합니다.
robroc

9
당신은 항상 이것을 할 수 있었다;)[f for f_ in [glob.glob(e) for e in ('*.jpg', '*.mp4')] for f in f_]
AlexG

1
files_grabbed = [ [ ' .pdf', '* .cpp'] 에서 e의 glob.glob (e) ]
florisla

3
파일 목록을 두 번 반복합니다. 첫 번째 반복에서는 * .pdf를 확인하고 두 번째 반복에서는 * .cpp를 확인합니다. 한 번의 반복으로 수행 할 수있는 방법이 있습니까? 매번 결합 상태를 확인 하시겠습니까?
Ridhuvarshan

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

44

glob 리스트를 반환합니다. 왜 여러 번 실행하고 결과를 연결하지 않습니까?

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

2
이것은 아마도 가장 읽기 쉬운 솔루션입니다. 나는의 경우 변경됩니다 ProjectFilesprojectFiles,하지만 훌륭한 솔루션을.
한스 골드만

40

결과를 연결하십시오 :

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

13
glob.glob-> glob.iglob-iterators 체인이 완전히 게으른 평가
rodrigob

1
나는 같은 해결책을 찾았지만에 대해 몰랐다 chain.from_iterable. 따라서 이것은 비슷하지만 읽기 쉽지 않습니다 it.chain(*(glob.iglob(pattern) for pattern in patterns)).
florisla

17

확장 프로그램 수만큼 여러 번 globbing을 제안하는 많은 답변을 대신 한 번만 globbing을 선호합니다.

from pathlib import Path

files = {p.resolve() for p in Path(path).glob("**/*") if p.suffix in [".c", ".cc", ".cpp", ".hxx", ".h"]}

15

glob으로는 불가능합니다. 당신은 다음을 사용할 수 있습니다 :
* 모든 것과 일치
합니까? 모든 단일 문자와 일치
[seq] seq의 모든 문자와 일치
[! seq]는 seq에없는 모든 문자와 일치

os.listdir 및 regexp를 사용하여 패턴을 확인하십시오.

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

10
파일 이름의 끝과 일치하도록 $로 정규 표현식을 끝내십시오
ThiefMaster

1
글로브의 표현력이 충분히 강력하지 않으면 더 강력한 정규식 시스템으로 업그레이드하고, 예를 들어 itertools후속 패턴 변경이 해킹 되어야하므로 (대소 문자를 허용하기 위해) 해킹하지 마십시오. . 아, 그리고 작성하는 것이 더 '.*\.(txt|sql)'
깨끗할

glob.iglob ( ' . ') 보다 os.listdir ( '.')을 선호하는 이유가 있습니까?
Mr.WorshipMe

14

예를 들어, 위해 *.mp3*.flac여러 폴더에, 당신은 할 수 있습니다 :

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

이 아이디어는 더 많은 파일 확장자로 확장 될 수 있지만 그 조합이 해당 폴더에있는 다른 원치 않는 파일 확장자와 일치하지 않는지 확인해야합니다. 따라서 조심 하십시오.

임의의 확장자 목록을 단일 glob 패턴으로 자동 결합하려면 다음을 수행하십시오.

mask_base = r'music/*/*.'
exts = ['mp3', 'flac', 'wma']
chars = ''.join('[{}]'.format(''.join(set(c))) for c in zip(*exts))
mask = mask_base + chars + ('*' if len(set(len(e) for e in exts)) > 1 else '')
print(mask)  # music/*/*.[fmw][plm][3a]*

6

하나의 라이너, 그냥 지옥 ..

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

4

도움을 받기 위해 여기에 온 후, 나는 나만의 솔루션을 만들어 공유하고 싶었습니다. 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

나를 위해 작동하지 않습니다. 내가 사용directoryPath = "/Users/bla/bla/images_dir*."
NeStack

디버깅을 위해 더 많은 정보가 필요합니다 ... 예외가 있습니까? 또한 Windows를 사용하는 경우 해당 경로가 작동하지 않는 것처럼 보입니다 (드라이브 문자 누락).
한스 골드만

4
files = glob.glob('*.txt')
files.extend(glob.glob('*.dat'))

4
좋은 답변은 코드에 대한 설명과 코드에 대한 추론도 제공합니다.
SunSparc

4

파이썬의 기본 glob는 Bash의 glob 뒤에 실제로 따르지 않지만 다른 라이브러리를 사용 하여이 작업을 수행 할 수 있습니다. wcmatch의 glob 에서 중괄호를 활성화 할 수 있습니다 .

>>> from wcmatch import glob
>>> glob.glob('*.{md,ini}', flags=glob.BRACE)
['LICENSE.md', 'README.md', 'tox.ini']

선호하는 경우 확장 글로브 패턴을 사용할 수도 있습니다 .

from wcmatch import glob
>>> glob.glob('*.@(md|ini)', flags=glob.EXTGLOB)
['LICENSE.md', 'README.md', 'tox.ini']

recursive플래그를 하지 않습니다
Shamoon

@Shamoon 아니요, glob.GLOBSTAR깃발 이 필요합니다
facelessuser

3

Apache Ant의 FileSet 및 Globs와 유사한 방식으로 여러 포함을 구현하는 Formic 을 출시 했습니다 .

검색을 구현할 수 있습니다 :

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 파일 만 선택하고 다른 서브 디렉토리에서는 .markdown 만 선택할 수 있습니다.

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

이게 도움이 되길 바란다.


3

다음 기능 _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")

3

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

또한로 시작하는 모든 파일 이름은 무시합니다 ~.


3

다음은 Pat의 답변에 대한 한 줄의 목록 이해 변형입니다 (특정 프로젝트 디렉토리에서 가져오고 싶었던 것도 포함).

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)을 반복 한 다음 각 확장명에 대해 각 패턴 ( for f in glob.glob(os.path.join(project_dir, ext))과 일치하는 각 파일을 가져옵니다 .

이 솔루션은 짧고 불필요한 for 루프, 중첩 목록 이해 또는 코드를 어지럽히는 기능이 없습니다. 순수하고 표현력있는 파이톤 입니다.

이 솔루션을 사용하면 exts코드를 업데이트하지 않고도 사용자 정의 목록을 변경할 수 있습니다. (이것은 항상 좋은 습관입니다!)

list-comprehension은 Laurent의 솔루션 (투표 한)과 동일합니다. 그러나 별도의 기능으로 한 줄을 제외하는 것이 일반적으로 필요하지 않다고 주장하므로 대안 솔루션으로 제공하고 있습니다.

보너스:

단일 디렉토리뿐만 아니라 모든 서브 디렉토리도 검색해야하는 경우 recursive=True다중 디렉토리 glob 기호 ** 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 기술적으로 **glob 기호는 슬래시를 포함하여 하나 이상의 문자와 일치 /합니다 (단일 *glob 기호 와 달리 ). 실제로는 **슬래시 (경로 구분 기호)로 둘러싸면 0 개 이상의 디렉토리와 일치 한다는 사실 만 기억하면됩니다 .


2

아니 glob,하지만 여기에 지능형리스트를 사용하여 다른 방법이있다 :

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

1

기존 확장과 필요한 확장을 비교하여 수동 목록을 만들 수 있습니다.

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)


1

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

1

확장명 목록을 사용하고 반복

from os.path import join
from glob import glob

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

print(files)

0

필터를 사용할 수 있습니다 :

import os
import glob

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

0

다음 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()각 패턴에 대한 목록이 만들어 지고 단일 목록으로 줄어 듭니다.


0

하나의 글로브, 많은 확장명 ...하지만 불완전한 솔루션 (다른 파일과 일치 할 수 있음).

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

나는 같은 문제가 있었고 이것이 내가 생각해 낸 것입니다.

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

또 다른 해결책은 (사용하는 glob여러 일치를 사용하여 경로를 얻을 수 patterns및 사용하여 하나의 목록으로 모든 경로를 결합 reduce하고 add) :

import functools, glob, operator
paths = functools.reduce(operator.add, [glob.glob(pattern) for pattern in [
    "path1/*.ext1",
    "path2/*.ext2"]])

0

사용하는 경우 다음을 pathlib시도하십시오.

import pathlib

extensions = ['.py', '.txt']
root_dir = './test/'

files = filter(lambda p: p.suffix in extensions, pathlib.Path(root_dir).glob('**/*'))

print(list(files))

0

경험적 테스트에서 얻은 결과에 따르면 glob.glob확장명으로 파일을 필터링하는 더 좋은 방법은 아닙니다. 그 이유 중 일부는 다음과 같습니다.

  • gloving " language "는 다중 확장을 완벽하게 지정할 수 없습니다.
  • 전자는 파일 확장자에 따라 잘못된 결과를 얻습니다.
  • globbing 방법은 다른 대부분의 방법보다 느리게 경험적으로 입증되었습니다.
  • 다른 파일 시스템 객체라도 " 확장자 "를 가질 수있는 것이 이상하더라도 폴더도 마찬가지입니다.

4확장명으로 파일을 필터링하고 파일을 넣는 다음과 같은 다양한 방법을 테스트했습니다 (시간의 정확성과 효율성) list.

from glob import glob, iglob
from re import compile, findall
from os import walk


def glob_with_storage(args):

    elements = ''.join([f'[{i}]' for i in args.extensions])
    globs = f'{args.target}/**/*{elements}'
    results = glob(globs, recursive=True)

    return results


def glob_with_iteration(args):

    elements = ''.join([f'[{i}]' for i in args.extensions])
    globs = f'{args.target}/**/*{elements}'
    results = [i for i in iglob(globs, recursive=True)]

    return results


def walk_with_suffixes(args):

    results = []
    for r, d, f in walk(args.target):
        for ff in f:
            for e in args.extensions:
                if ff.endswith(e):
                    results.append(path_join(r,ff))
                    break
    return results


def walk_with_regs(args):

    reg = compile('|'.join([f'{i}$' for i in args.extensions]))

    results = []
    for r, d, f in walk(args.target):
        for ff in f:
            if len(findall(reg,ff)):
                results.append(path_join(r, ff))

    return results

랩톱에서 위의 코드를 실행하여 다음과 같은 자동 설명 결과를 얻었습니다.

Elapsed time for '7 times glob_with_storage()':  0.365023 seconds.
mean   : 0.05214614
median : 0.051861
stdev  : 0.001492152
min    : 0.050864
max    : 0.054853

Elapsed time for '7 times glob_with_iteration()':  0.360037 seconds.
mean   : 0.05143386
median : 0.050864
stdev  : 0.0007847381
min    : 0.050864
max    : 0.052859

Elapsed time for '7 times walk_with_suffixes()':  0.26529 seconds.
mean   : 0.03789857
median : 0.037899
stdev  : 0.0005759071
min    : 0.036901
max    : 0.038896

Elapsed time for '7 times walk_with_regs()':  0.290223 seconds.
mean   : 0.04146043
median : 0.040891
stdev  : 0.0007846776
min    : 0.04089
max    : 0.042885

Results sizes:
0 2451
1 2451
2 2446
3 2446

Differences between glob() and walk():
0 E:\x\y\z\venv\lib\python3.7\site-packages\Cython\Includes\numpy
1 E:\x\y\z\venv\lib\python3.7\site-packages\Cython\Utility\CppSupport.cpp
2 E:\x\y\z\venv\lib\python3.7\site-packages\future\moves\xmlrpc
3 E:\x\y\z\venv\lib\python3.7\site-packages\Cython\Includes\libcpp
4 E:\x\y\z\venv\lib\python3.7\site-packages\future\backports\xmlrpc

Elapsed time for 'main':  1.317424 seconds.

확장명으로 파일을 필터링하는 가장 빠른 방법은 가장 추악한 것입니다. 즉, 중첩 for루프 및 메소드를 string사용한 비교 endswith()입니다.

또한 보시다시피, 확장 ( 과 ) E:\x\y\z\**/*[py][pyc]만으로도 globbing 알고리즘 (패턴 포함 ) 은 잘못된 결과를 반환합니다.2pypyc


0
import glob
import pandas as pd

df1 = pd.DataFrame(columns=['A'])
for i in glob.glob('C:\dir\path\*.txt'):
    df1 = df1.append({'A': i}, ignore_index=True)
for i in glob.glob('C:\dir\path\*.mdown'):
    df1 = df1.append({'A': i}, ignore_index=True)
for i in glob.glob('C:\dir\path\*.markdown):
    df1 = df1.append({'A': i}, ignore_index=True)

안녕하세요 Sway Wu, 환영합니다. 설명을 추가해보십시오.
Tiago Martins Peres 李大仁

-1

이것은 작동해야합니다 :

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

-1

예를 들면 다음과 같습니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.