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'))
그러나 이것은 분명히 제한적이고 투박합니다.
Python 3.5 이상
새로운 파이썬을 사용 pathlib.Path.glob
하고 있으므로 pathlib
모듈 에서 사용해야 합니다.
from pathlib import Path
for filename in Path('src').glob('**/*.c'):
print(filename)
pathlib를 사용하지 않으려면을 사용 glob.glob
하고 recursive
키워드 매개 변수 를 전달하는 것을 잊지 마십시오 .
점 (.);으로 시작하는 파일이 일치하는 경우 현재 디렉토리의 파일이나 Unix 기반 시스템의 숨겨진 파일과 같이 os.walk
아래 솔루션을 사용하십시오 .
이전 Python 버전
이전 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
).
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))
다음은 중첩 된 목록 이해 os.walk
및 glob
다음 대신 간단한 접미사 일치를 사용 하는 솔루션 입니다 .
import os
cfiles = [os.path.join(root, filename)
for root, dirnames, filenames in os.walk('src')
for filename in filenames if filename.endswith('.c')]
한 줄로 압축 할 수 있습니다.
import os;cfiles=[os.path.join(r,f) for r,d,fs in os.walk('src') for f in fs if f.endswith('.c')]
또는 함수로 일반화 :
import os
def recursive_glob(rootdir='.', suffix=''):
return [os.path.join(looproot, filename)
for looproot, _, filenames in os.walk(rootdir)
for filename in filenames if filename.endswith(suffix)]
cfiles = recursive_glob('src', '.c')
전체 glob
스타일 패턴 이 필요한 경우 Alex와 Bruno의 예를 따라 다음을 사용할 수 있습니다 fnmatch
.
import fnmatch
import os
def recursive_glob(rootdir='.', pattern='*'):
return [os.path.join(looproot, filename)
for looproot, _, filenames in os.walk(rootdir)
for filename in filenames
if fnmatch.fnmatch(filename, pattern)]
cfiles = recursive_glob('src', '*.c')
최근에 .jpg 확장자로 사진을 복구해야했습니다. 나는 photorec을 실행하고 그 안에서 220 만개의 파일을 복구 한 4579 개의 디렉토리를 엄청나게 다양한 확장자로 복구했습니다. 아래 스크립트를 사용하여 몇 분 안에 .jpg 확장자를 가진 50133 개의 파일을 선택할 수있었습니다.
#!/usr/binenv python2.7
import glob
import shutil
import os
src_dir = "/home/mustafa/Masaüstü/yedek"
dst_dir = "/home/mustafa/Genel/media"
for mediafile in glob.iglob(os.path.join(src_dir, "*", "*.jpg")): #"*" is for subdirectory
shutil.copy(mediafile, dst_dir)
Johan과 Bruno는 언급 된 최소한의 요구 사항에 대한 탁월한 솔루션을 제공합니다. 저는이 문제와 더 복잡한 시나리오를 처리 할 수있는 Ant FileSet 및 Globs 를 구현하는 Formic 을 방금 출시했습니다 . 요구 사항의 구현은 다음과 같습니다.
import formic
fileset = formic.FileSet(include="/src/**/*.c")
for file_name in fileset.qualified_files():
print file_name
다른 답변을 기반으로 이것은 루트 디렉토리에서 중첩 된 xml 파일을 검색하는 현재 작업 구현입니다.
files = []
for root, dirnames, filenames in os.walk(myDir):
files.extend(glob.glob(root + "/*.xml"))
나는 정말 파이썬으로 재미있다 :)
고려하십시오 pathlib.rglob()
.
이것은 주어진 상대 패턴 앞에 add
Path.glob()
를 호출 하는 것과 같습니다"**/"
.
import pathlib
for p in pathlib.Path("src").rglob("*.c"):
print(p)
여기에서 @taleinat의 관련 게시물 과 다른 곳 의 이전 게시물을 참조하십시오 .
glob 모듈을 사용하는 또 다른 방법입니다. 시작 기본 디렉토리와 일치시킬 패턴으로 rglob 메소드를 시드하면 일치하는 파일 이름 목록이 반환됩니다.
import glob
import os
def _getDirs(base):
return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ]
def rglob(base, pattern):
list = []
list.extend(glob.glob(os.path.join(base,pattern)))
dirs = _getDirs(base)
if len(dirs):
for d in dirs:
list.extend(rglob(os.path.join(base,d), pattern))
return list
방금 만든 .. 파일과 디렉토리를 계층 적으로 인쇄합니다.
하지만 fnmatch 나 walk를 사용하지 않았어요
#!/usr/bin/python
import os,glob,sys
def dirlist(path, c = 1):
for i in glob.glob(os.path.join(path, "*")):
if os.path.isfile(i):
filepath, filename = os.path.split(i)
print '----' *c + filename
elif os.path.isdir(i):
dirname = os.path.basename(i)
print '----' *c + dirname
c+=1
dirlist(i,c)
c-=1
path = os.path.normpath(sys.argv[1])
print(os.path.basename(path))
dirlist(path)
그 사람은 fnmatch 또는 정규식을 사용합니다.
import fnmatch, os
def filepaths(directory, pattern):
for root, dirs, files in os.walk(directory):
for basename in files:
try:
matched = pattern.match(basename)
except AttributeError:
matched = fnmatch.fnmatch(basename, pattern)
if matched:
yield os.path.join(root, basename)
# usage
if __name__ == '__main__':
from pprint import pprint as pp
import re
path = r'/Users/hipertracker/app/myapp'
pp([x for x in filepaths(path, re.compile(r'.*\.py$'))])
pp([x for x in filepaths(path, '*.py')])
제안 된 답변 외에도 지연 생성 및 목록 이해 마법으로이를 수행 할 수 있습니다.
import os, glob, itertools
results = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.c'))
for root, dirs, files in os.walk('src'))
for f in results: print(f)
Besides fitting in one line and avoiding unnecessary lists in memory, this also has the nice side effect, that you can use it in a way similar to the ** operator, e.g., you could use os.path.join(root, 'some/path/*.c')
in order to get all .c files in all sub directories of src that have this structure.
For python >= 3.5 you can use **
, recursive=True
:
import glob
for x in glob.glob('path/**/*.c', recursive=True):
print(x)
If recursive is true, the pattern
**
will match any files and zero or moredirectories
andsubdirectories
. If the pattern is followed by anos.sep
, only directories andsubdirectories
match.
Simplified version of Johan Dahlin's answer, without fnmatch.
import os
matches = []
for root, dirnames, filenames in os.walk('src'):
matches += [os.path.join(root, f) for f in filenames if f[-2:] == '.c']
Or with a list comprehension:
>>> base = r"c:\User\xtofl"
>>> binfiles = [ os.path.join(base,f)
for base, _, files in os.walk(root)
for f in files if f.endswith(".jpg") ]
Here is my solution using list comprehension to search for multiple file extensions recursively in a directory and all subdirectories:
import os, glob
def _globrec(path, *exts):
""" Glob recursively a directory and all subdirectories for multiple file extensions
Note: Glob is case-insensitive, i. e. for '\*.jpg' you will get files ending
with .jpg and .JPG
Parameters
----------
path : str
A directory name
exts : tuple
File extensions to glob for
Returns
-------
files : list
list of files matching extensions in exts in path and subfolders
"""
dirs = [a[0] for a in os.walk(path)]
f_filter = [d+e for d in dirs for e in exts]
return [f for files in [glob.iglob(files) for files in f_filter] for f in files]
my_pictures = _globrec(r'C:\Temp', '\*.jpg','\*.bmp','\*.png','\*.gif')
for f in my_pictures:
print f
import sys, os, glob
dir_list = ["c:\\books\\heap"]
while len(dir_list) > 0:
cur_dir = dir_list[0]
del dir_list[0]
list_of_files = glob.glob(cur_dir+'\\*')
for book in list_of_files:
if os.path.isfile(book):
print(book)
else:
dir_list.append(book)
I modified the top answer in this posting.. and recently created this script which will loop through all files in a given directory (searchdir) and the sub-directories under it... and prints filename, rootdir, modified/creation date, and size.
Hope this helps someone... and they can walk the directory and get fileinfo.
import time
import fnmatch
import os
def fileinfo(file):
filename = os.path.basename(file)
rootdir = os.path.dirname(file)
lastmod = time.ctime(os.path.getmtime(file))
creation = time.ctime(os.path.getctime(file))
filesize = os.path.getsize(file)
print "%s**\t%s\t%s\t%s\t%s" % (rootdir, filename, lastmod, creation, filesize)
searchdir = r'D:\Your\Directory\Root'
matches = []
for root, dirnames, filenames in os.walk(searchdir):
## for filename in fnmatch.filter(filenames, '*.c'):
for filename in filenames:
## matches.append(os.path.join(root, filename))
##print matches
fileinfo(os.path.join(root, filename))
Here is a solution that will match the pattern against the full path and not just the base filename.
It uses fnmatch.translate
to convert a glob-style pattern into a regular expression, which is then matched against the full path of each file found while walking the directory.
re.IGNORECASE
is optional, but desirable on Windows since the file system itself is not case-sensitive. (I didn't bother compiling the regex because docs indicate it should be cached internally.)
import fnmatch
import os
import re
def findfiles(dir, pattern):
patternregex = fnmatch.translate(pattern)
for root, dirs, files in os.walk(dir):
for basename in files:
filename = os.path.join(root, basename)
if re.search(patternregex, filename, re.IGNORECASE):
yield filename
I needed a solution for python 2.x that works fast on large directories.
I endet up with this:
import subprocess
foundfiles= subprocess.check_output("ls src/*.c src/**/*.c", shell=True)
for foundfile in foundfiles.splitlines():
print foundfile
Note that you might need some exception handling in case ls
doesn't find any matching file.
For python 3.5 and later
file_names_array = glob.glob('src/*.c', recursive=True)
Edit: As @NeStack guided if above does not work for you, please try
file_names_array = glob.glob('src/**.c', recursive=True)
further you might need
for full_path_in_src in file_names_array:
print (full_path_in_src ) # be like 'abc/xyz.c'
#Full system path of this would be like => 'path till src/abc/xyz.c'
참고URL : https://stackoverflow.com/questions/2186525/how-to-use-glob-to-find-files-recursively
'Programing' 카테고리의 다른 글
Windows cmd stdout 및 stderr을 단일 파일로 리디렉션 (0) | 2020.10.02 |
---|---|
파일의 전체 경로를 얻는 방법은 무엇입니까? (0) | 2020.10.02 |
SQL은 SELECT * [columnA 제외] FROM tableA를 사용하여 열을 제외합니까? (0) | 2020.10.02 |
IEnumerable의 동적 LINQ OrderBy (0) | 2020.10.02 |
Java에서 현재 날짜 / 시간을 얻는 방법 (0) | 2020.10.02 |