답변:
파이썬 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.path.walk()
더 이상 사용되지 않으며 파이썬 3에서 제거되었다는 것을 알리는 것 입니다.
pathlib.Path('src').glob('**/*.c')
작동합니다.
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
또한 생성기를 사용하면 모든 파일을 찾아서 처리하는 대신 발견 된대로 각 파일 을 처리 할 수 있습니다.
reduce(lambda x, y: x+y, map(lambda (r,_,x):map(lambda f: r+'/'+f, filter(lambda f: fnmatch.fnmatch(f, pattern), x)), os.walk('src/webapp/test_scripts')))
(os.path.join(root,filename) for root, dirs, files in os.walk(directory) for filename in files if fnmatch.fnmatch(filename, pattern))
재귀 globbing을 지원하기 위해 glob 모듈을 수정했습니다. 예 :
>>> import glob2
>>> all_header_files = glob2.glob('src/**/*.c')
https://github.com/miracle2k/python-glob2/
** 구문을 사용할 수있는 기능을 사용자에게 제공 할 때 유용하므로 os.walk ()만으로는 충분하지 않습니다.
**
공식 glob 모듈을 사용하여 재귀 globbing을 활성화하려면 다음 과 같이하십시오.glob(path, recursive=True)
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
표시).
recursive_glob(pattern, treeroot='.')
편집 할 때 제안한대로 사용하는 것에 대해 어떻게 생각 하십니까? 이러한 방식으로 예를 들어 recursive_glob('*.txt')
의 구문과 직관적으로 일치 하도록 호출 할 수 있습니다 glob
.
fnmatch.filter
와 일치하는데, 이는 single-argument 일치 가능성만큼이나 유용합니다 glob.glob
.
파이썬> = 3.5 사용할 수있는 **
, recursive=True
:
import glob
for x in glob.glob('path/**/*.c', recursive=True):
print(x)
재귀 인 경우
True
, 패턴은**
모든 파일과 0 개 이상의 일치directories
와subdirectories
. 패턴 다음에가 오는os.sep
경우 디렉토리 만subdirectories
일치합니다.
다음은 중첩 목록 이해 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 만 개의 파일을 220 만 개의 파일로 복구했습니다. 아래 스크립트를 사용하면 몇 분 안에 50133 파일 havin .jpg 확장자를 선택할 수있었습니다
#!/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)
고려하십시오 pathlib.rglob()
.
이것은 주어진 상대 패턴 앞에 추가하여 호출
Path.glob()
하는 것과 같습니다"**/"
.
import pathlib
for p in pathlib.Path("src").rglob("*.c"):
print(p)
Johan과 Bruno는 명시된 최소 요구 사항에 대한 탁월한 솔루션을 제공합니다. 방금 이 복잡한 시나리오를 처리 할 수있는 Ant FileSet 및 Glob 을 구현하는 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"))
나는 정말로 파이썬과 재미있다 :)
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
파이썬 3.5 이상
import glob
#file_names_array = glob.glob('path/*.c', recursive=True)
#above works for files directly at path/ as guided by NeStack
#updated version
file_names_array = glob.glob('path/**/*.c', recursive=True)
또한 당신은 필요할 수 있습니다
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'
/**
그것은 나를 위해 다음과 같이 작동합니다 :file_names_array = glob.glob('src/**/*.c', recursive=True)
방금 만들었습니다. 파일과 디렉토리를 계층 적으로 인쇄합니다.
그러나 나는 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)
한 줄에 맞추고 메모리에 불필요한 목록을 피하는 것 외에도 ** 연산자와 비슷한 방식으로 사용할 수있는 부작용이 있습니다. 예를 들어 os.path.join(root, 'some/path/*.c')
모든 .c 파일을 모두 가져 오기 위해 사용할 수 있습니다 이 구조를 가진 src의 하위 디렉토리.
이것은 Python 2.7에서 작동하는 코드입니다. 개발자 작업의 일환으로 live-appName.properties로 표시된 구성 파일을 appName.properties로 이동시키는 스크립트를 작성해야했습니다. live-appName.xml과 같은 다른 확장 파일이있을 수 있습니다.
아래는 이것에 대한 작업 코드입니다.이 디렉토리는 주어진 디렉토리 (중첩 수준)에서 파일을 찾은 다음 필요한 파일 이름으로 이름을 변경 (이동)합니다.
def flipProperties(searchDir):
print "Flipping properties to point to live DB"
for root, dirnames, filenames in os.walk(searchDir):
for filename in fnmatch.filter(filenames, 'live-*.*'):
targetFileName = os.path.join(root, filename.split("live-")[1])
print "File "+ os.path.join(root, filename) + "will be moved to " + targetFileName
shutil.move(os.path.join(root, filename), targetFileName)
이 함수는 기본 스크립트에서 호출됩니다
flipProperties(searchDir)
이것이 비슷한 문제로 어려움을 겪고있는 누군가를 돕기를 바랍니다.
다음은 디렉토리와 모든 하위 디렉토리에서 재귀 적 으로 여러 파일 확장자 를 검색하기 위해 목록 이해를 사용하는 솔루션입니다 .
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
나는이 게시물의 최상위 답변을 수정했습니다. 최근에는 주어진 디렉토리 (searchdir) 및 그 아래의 하위 디렉토리에있는 모든 파일을 반복하고 파일 이름, rootdir, 수정 / 생성 날짜 및 크기.
이것이 누군가에게 도움이되기를 바랍니다 ... 그들은 디렉토리를 걷고 파일 정보를 얻을 수 있습니다.
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))
기본 파일 이름뿐만 아니라 전체 경로와 패턴을 일치시키는 솔루션이 있습니다.
사용합니다 fnmatch.translate
glob 스타일 패턴을 정규식으로 변환하는 되며, 이는 디렉토리를 걷는 동안 발견 된 각 파일의 전체 경로와 일치합니다.
re.IGNORECASE
파일 시스템 자체는 대소 문자를 구분하지 않으므로 Windows에서는 선택 사항이지만 Windows에서는 바람직합니다. (문서가 내부적으로 캐시되어야 함을 나타 내기 때문에 정규식을 컴파일하는 것을 귀찮게하지 않았습니다.)
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
큰 디렉토리에서 빠르게 작동 하는 python 2.x 솔루션이 필요했습니다 .
나는 이것으로 끝났다.
import subprocess
foundfiles= subprocess.check_output("ls src/*.c src/**/*.c", shell=True)
for foundfile in foundfiles.splitlines():
print foundfile
ls
일치하는 파일을 찾지 못하면 예외 처리가 필요할 수 있습니다 .
os.path.walk()
약간 더 사용하기가os.walk()