[python] glob ()를 사용하여 재귀 적으로 파일을 찾는 방법은 무엇입니까?

이것이 내가 가진 것입니다 :

glob(os.path.join('src','*.c'))

src의 하위 폴더를 검색하고 싶습니다. 이와 같은 것이 효과가 있습니다.

glob(os.path.join('src','*.c'))
glob(os.path.join('src','*','*.c'))
glob(os.path.join('src','*','*','*.c'))
glob(os.path.join('src','*','*','*','*.c'))

그러나 이것은 분명히 제한적이고 어수선합니다.



답변

파이썬 3.5 이상

새로운 파이썬을 사용 pathlib.Path.rglob하고 있으므로 pathlib모듈 에서 사용해야 합니다.

from pathlib import Path

for path in Path('src').rglob('*.c'):
    print(path.name)

pathlib를 사용하지 않으려면을 사용 glob.glob하지만 recursive키워드 매개 변수 를 전달하는 것을 잊지 마십시오 .

일치하는 파일이 점 (.)으로 시작하는 경우 현재 디렉토리의 파일 또는 Unix 기반 시스템의 숨겨진 파일과 같이 os.walk아래 솔루션을 사용하십시오 .

이전 파이썬 버전

이전 Python 버전의 os.walk경우 디렉토리를 재귀 적으로 탐색 fnmatch.filter하고 간단한 표현식과 일치시키는 데 사용하십시오.

import fnmatch
import os

matches = []
for root, dirnames, filenames in os.walk('src'):
    for filename in fnmatch.filter(filenames, '*.c'):
        matches.append(os.path.join(root, filename))


답변

os.walk가 이미 파일 이름을 나열 했으므로 다른 솔루션과 유사하지만 glob 대신 fnmatch.fnmatch를 사용합니다.

import os, fnmatch


def find_files(directory, pattern):
    for root, dirs, files in os.walk(directory):
        for basename in files:
            if fnmatch.fnmatch(basename, pattern):
                filename = os.path.join(root, basename)
                yield filename


for filename in find_files('src', '*.c'):
    print 'Found C source:', filename

또한 생성기를 사용하면 모든 파일을 찾아서 처리하는 대신 발견 된대로 각 파일 처리 할 수 ​​있습니다.


답변

재귀 globbing을 지원하기 위해 glob 모듈을 수정했습니다. 예 :

>>> import glob2
>>> all_header_files = glob2.glob('src/**/*.c')

https://github.com/miracle2k/python-glob2/

** 구문을 사용할 수있는 기능을 사용자에게 제공 할 때 유용하므로 os.walk ()만으로는 충분하지 않습니다.


답변

Python 3.4부터는 와일드 카드 를 지원 하는 새로운 pathlib 모듈 에서 클래스 glob()중 하나의 메소드를 사용할 수 있습니다 . 예를 들면 다음과 같습니다.Path**

from pathlib import Path

for file_path in Path('src').glob('**/*.c'):
    print(file_path) # do whatever you need with these files

업데이트 :
Python 3.5부터는 동일한 구문이 지원됩니다 glob.glob().


답변

import os
import fnmatch


def recursive_glob(treeroot, pattern):
    results = []
    for base, dirs, files in os.walk(treeroot):
        goodfiles = fnmatch.filter(files, pattern)
        results.extend(os.path.join(base, f) for f in goodfiles)
    return results

fnmatch와 정확히 동일한 패턴을 제공 glob하므로 glob.glob매우 가까운 의미론을 대체 할 수 있습니다. IOW의 대체 버전 인 반복 버전 (예 : 생성기) glob.iglob은 사소한 조정입니다 ( 단일 결과 목록을 반환하는 yield대신 중간 결과 만 extend표시).


답변

파이썬> = 3.5 사용할 수있는 **, recursive=True:

import glob
for x in glob.glob('path/**/*.c', recursive=True):
    print(x)

데모


재귀 인 경우 True, 패턴은 ** 모든 파일과 0 개 이상의 일치 directoriessubdirectories . 패턴 다음에가 오는 os.sep경우 디렉토리 만 subdirectories일치합니다.


답변

os.walk기준과 일치하는 파일 이름을 수집하는 데 사용하려고 합니다. 예를 들면 다음과 같습니다.

import os
cfiles = []
for root, dirs, files in os.walk('src'):
  for file in files:
    if file.endswith('.c'):
      cfiles.append(os.path.join(root, file))