programing

Python glob 다중 파일 형식

shortcode 2022. 11. 4. 22:10
반응형

Python glob 다중 파일 형식

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

더 나은 방법이 있을 수 있지만, 다음 사항은 어떻습니까?

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

다른 방법이 있을지도 모르니 다른 사람이 더 좋은 답을 내놓을지 기다려라.

glob목록을 반환합니다.여러 번 실행하고 결과를 연결하면 어떨까요?

from glob import glob
project_files = glob('*.txt') + glob('*.mdown') + glob('*.markdown')
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)

확장자 수만큼 글로벌화를 제안할 수 있는 답변이 너무 많아서 대신 글로벌화를 한 번만 했으면 합니다.

from pathlib import Path

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

결과 체인:

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

를 들면, 「」의 는,*.mp3 ★★★★★★★★★★★★★★★★★」*.flac여러 폴더에서 다음을 수행할 수 있습니다.

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

아이디어를 더 많은 파일 확장자로 확장할 수 있지만, 이러한 폴더에 있는 다른 원하지 않는 파일 확장자와 조합이 일치하지 않는지 확인해야 합니다.그러니까 이거 조심하세요.

임의의 확장 리스트를 1개의 글로벌패턴에 자동적으로 조합하려면 , 다음의 조작은 다음과 같습니다.

def multi_extension_glob_mask(mask_base, *extensions):
    mask_ext = ['[{}]'.format(''.join(set(c))) for c in zip(*extensions)]
    if not mask_ext or len(set(len(e) for e in extensions)) > 1:
        mask_ext.append('*')
    return mask_base + ''.join(mask_ext)

mask = multi_extension_glob_mask('music/*/*.', 'mp3', 'flac', 'wma')
print(mask)  # music/*/*.[mfw][pml][a3]*

glob에서는 .을 사용하다
everything*은 모두 일치합니다.
문자와 합니까?는 임의의 단일 문자와 일치합니다.
[seq]의 임의의 합니다.
[!seq]에 없는 합니다.

패턴을 확인하려면 os.listdir 및 regexp를 사용합니다.

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

Python의 기본 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']

@BPL(계산 효율)과 같은 답변이지만 확장자가 아닌 모든 글로벌 패턴을 처리할 수 있습니다.

import os
from fnmatch import fnmatch

folder = "path/to/folder/"
patterns = ("*.txt", "*.md", "*.markdown")

files = [f.path for f in os.scandir(folder) if any(fnmatch(f, p) for p in patterns)]

이 솔루션은 효율적이고 편리합니다., ,, 과, of, 그의 행동과 매우 합니다.glob(매뉴얼 참조).

은, 「」가 짜넣어져 있기 에, 한 것에 해 주세요.pathlib:

from pathlib import Path

folder = Path("/path/to/folder")
patterns = ("*.txt", "*.md", "*.markdown")

files = [f for f in folder.iterdir() if any(f.match(p) for p in patterns)]

다음은 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)를 참조해 주세요.

이 솔루션은 짧고 불필요한 루프, 중첩된 목록 통합 또는 코드를 복잡하게 만드는 함수가 없습니다.순수하고 표현력이 풍부한 피조어 선일 뿐이죠

이 솔루션에서는, 다음의 커스텀 리스트를 작성할 수 있습니다.exts(어느쪽인가!)

목록 이해는 Laurent의 솔루션에서 사용된 것과 같습니다.그러나 보통 한 줄을 다른 함수에 대입할 필요는 없다고 생각합니다.그래서 저는 이것을 대체 해결책으로 제공하고 있습니다.

보너스:

는, 「」를 건네줄 수 .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 엄밀히 말하면**glob 기호는 단순히 정방향 문자를 포함한 하나 이상의 문자와 일치합니다. /)*★★★★★★★★★★★★★★★★」이렇게 된다는 .**슬래시(패스 구분자)를 사용하면 0개 이상의 디렉토리와 일치합니다.

그냥 재미삼아 한 줄만...

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']
files = glob.glob('*.txt')
files.extend(glob.glob('*.dat'))

내가 실증 테스트에서 얻은 결과에 따르면glob.glob확장자를 기준으로 파일을 필터링하는 더 좋은 방법은 아닙니다.중 몇 가지는 다음과 같습니다

  • 글로벌한 「언어」에서는, 복수의 확장자를 완전하게 지정할 수 없습니다.
  • 앞의 포인트는 파일 확장자에 따라 잘못된 결과를 얻을 수 있습니다.
  • 글로빙 방법은 대부분의 다른 방법보다 느리다는 것이 경험적으로 증명되었다.
  • 다른 파일 시스템 객체에도 "확장자"가 있는 것이 이상하지만 폴더도 마찬가지입니다.

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와 ""stringendswith()★★★★★★ 。

, , 패턴이다)이 있습니다.E:\x\y\z\**/*[py][pyc]2( 「내선번호」)py ★★★★★★★★★★★★★★★★★」pyc 결과가 에서도 잘못된 결과가 반환됩니다.

파이썬 3

하면 됩니다.pathlib.glob 또는 괄호 내쉘과 지원하지 쉽게 할 수 .filter결과

예를 들어, 이상적으로는 다음과 같은 작업을 수행할 수 있습니다.

# NOT VALID
Path(config_dir).glob("*.{ini,toml}")
# NOR IS
Path(config_dir).glob("*.ini", "*.toml")

다음 작업을 수행할 수 있습니다.

filter(lambda p: p.suffix in {".ini", ".toml"}, Path(config_dir).glob("*"))

더 나빠지진 않았어요

Apache Ant의 FileSetGlobs와 유사한 방법으로 여러 포함을 구현하는 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이 실장되어 있기 때문에, 각 패턴에 다른 디렉토리를 포함할 수 있습니다.따라서, 1개의 서브 디렉토리에서는 이러한 .txt 파일만을 선택하고, 다른 서브 디렉토리에서는 .markdown 파일을 선택할 수 있습니다.예를 들어 다음과 같습니다.

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

이게 도움이 됐으면 좋겠어요.

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

또한 다음 문자로 시작하는 모든 파일 이름을 무시합니다.~.

도움을 청하러 온 후, 나는 나만의 해결책을 만들었고 그것을 공유하고 싶었다.user 2363986의 답변에 근거하고 있습니다만, 이것이 확장성이 높다고 생각합니다.즉, 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

것은 아니다.glob목록 이해를 사용하는 다른 방법이 있습니다.

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

함수_globextensions.globs 。

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

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

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

로 으로.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()과 같은 값을 생성하는 반복기를 반환합니다.

def iglob_filetypes(root_dir, *patterns):
    return (path
            for pattern in patterns
            for path in glob.iglob(os.path.join(root_dir, pattern)))

글로브 하나, 많은 연장선...그러나 불완전한 솔루션(다른 파일과 일치할 수 있음).

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

「 」를 사용하고 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))

확장자 목록을 사용하여 를 반복합니다.

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)

이전 답변에서

glob('*.jpg') + glob('*.png')

여기 더 짧은 게 있어요.

from glob import glob
extensions = ['jpg', 'png'] # to find these filename extensions

# Method 1: loop one by one and extend to the output list
output = []
[output.extend(glob(f'*.{name}')) for name in extensions]
print(output)

# Method 2: even shorter
# loop filename extension to glob() it and flatten it to a list
output = [p for p2 in [glob(f'*.{name}') for name in extensions] for p in p2]
print(output)

나한텐 효과가 있었어!

split('.')[-1]

위의 코드는 파일 이름 서픽스(*.xx)를 구분하여 사용자에게 도움이 되도록 합니다.

    for filename in glob.glob(folder + '*.*'):
        print(folder+filename)
        if  filename.split('.')[-1] != 'tif' and \
            filename.split('.')[-1] != 'tiff' and \
            filename.split('.')[-1] != 'bmp' and \
            filename.split('.')[-1] != 'jpg' and \
            filename.split('.')[-1] != 'jpeg' and \
            filename.split('.')[-1] != 'png':
                continue
        # Your code

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

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()각 패턴에 대해 단일 목록으로 축소합니다.

언급URL : https://stackoverflow.com/questions/4568580/python-glob-multiple-filetypes

반응형