glob.glob 모듈을 사용하여 하위 폴더를 검색하려면 어떻게해야합니까?
폴더에서 일련의 하위 폴더를 열고 일부 텍스트 파일을 찾고 텍스트 파일의 일부 줄을 인쇄하고 싶습니다. 나는 이것을 사용하고있다 :
configfiles = glob.glob('C:/Users/sam/Desktop/file1/*.txt')
그러나 이것은 하위 폴더에도 액세스 할 수 없습니다. 누구든지 동일한 명령을 사용하여 하위 폴더에 액세스하는 방법을 알고 있습니까?
Python 3.5 이상에서는 새로운 재귀 **/
기능을 사용합니다 .
configfiles = glob.glob('C:/Users/sam/Desktop/file1/**/*.txt', recursive=True)
recursive
가 설정 되면 **
경로 구분 기호가 0 개 이상의 하위 디렉토리와 일치합니다.
이전 Python 버전에서는 glob.glob()
하위 디렉토리의 파일을 재귀 적으로 나열 할 수 없습니다.
이 경우 대신 다음 os.walk()
과 같이 사용 fnmatch.filter()
합니다.
import os
import fnmatch
path = 'C:/Users/sam/Desktop/file1'
configfiles = [os.path.join(dirpath, f)
for dirpath, dirnames, files in os.walk(path)
for f in fnmatch.filter(files, '*.txt')]
이것은 디렉토리를 재귀 적으로 걷고 모든 절대 경로 이름을 일치하는 .txt
파일로 반환 합니다. 이 특정 경우에는 fnmatch.filter()
과잉 일 수 있으며 .endswith()
테스트를 사용할 수도 있습니다 .
import os
path = 'C:/Users/sam/Desktop/file1'
configfiles = [os.path.join(dirpath, f)
for dirpath, dirnames, files in os.walk(path)
for f in files if f.endswith('.txt')]
바로 아래의 하위 디렉터리에서 파일을 찾으려면 :
configfiles = glob.glob(r'C:\Users\sam\Desktop\*\*.txt')
모든 하위 디렉토리를 순회하는 재귀 버전의 경우 Python 3.5부터 사용 **
하고 전달할 수 있습니다 .recursive=True
configfiles = glob.glob(r'C:\Users\sam\Desktop\**\*.txt', recursive=True)
두 함수 호출 모두 목록을 반환합니다. glob.iglob()
경로를 하나씩 반환 하는 데 사용할 수 있습니다 . 또는 다음을 사용하십시오pathlib
.
from pathlib import Path
path = Path(r'C:\Users\sam\Desktop')
txt_files_only_subdirs = path.glob('*/*.txt')
txt_files_all_recursively = path.rglob('*.txt') # including the current dir
두 메서드 모두 반복자를 반환합니다 (경로를 하나씩 가져올 수 있음).
glob2의 패키지는 와일드 카드를 지원하며 합리적으로 빠르게
code = '''
import glob2
glob2.glob("files/*/**")
'''
timeit.timeit(code, number=1)
내 랩톱에서는 60,000 개 이상의 파일 경로 를 일치시키는 데 약 2 초가 걸립니다 .
You can use Formic with Python 2.6
import formic
fileset = formic.FileSet(include="**/*.txt", directory="C:/Users/sam/Desktop/")
Disclosure - I am the author of this package.
There's a lot of confusion on this topic. Let me see if I can clarify it (Python 3.7):
glob.glob('*.txt') :
matches all files ending in '.txt' in current directoryglob.glob('*/*.txt') :
same as 1glob.glob('**/*.txt') :
matches all files ending in '.txt' in the immediate subdirectories only, but not in the current directoryglob.glob('*.txt',recursive=True) :
same as 1glob.glob('*/*.txt',recursive=True) :
same as 3glob.glob('**/*.txt',recursive=True):
matches all files ending in '.txt' in the current directory and in all subdirectories
So it's best to always specify recursive=True.
Here is a adapted version that enables glob.glob
like functionality without using glob2
.
def find_files(directory, pattern='*'):
if not os.path.exists(directory):
raise ValueError("Directory not found {}".format(directory))
matches = []
for root, dirnames, filenames in os.walk(directory):
for filename in filenames:
full_path = os.path.join(root, filename)
if fnmatch.filter([full_path], pattern):
matches.append(os.path.join(root, filename))
return matches
So if you have the following dir structure
tests/files
├── a0
│ ├── a0.txt
│ ├── a0.yaml
│ └── b0
│ ├── b0.yaml
│ └── b00.yaml
└── a1
You can do something like this
files = utils.find_files('tests/files','**/b0/b*.yaml')
> ['tests/files/a0/b0/b0.yaml', 'tests/files/a0/b0/b00.yaml']
Pretty much fnmatch
pattern match on the whole filename itself, rather than the filename only.
configfiles = glob.glob('C:/Users/sam/Desktop/**/*.txt")
Doesn't works for all cases, instead use glob2
configfiles = glob2.glob('C:/Users/sam/Desktop/**/*.txt")
If you can install glob2 package...
import glob2
filenames = glob2.glob("C:\\top_directory\\**\\*.ext") # Where ext is a specific file extension
folders = glob2.glob("C:\\top_directory\\**\\")
All filenames and folders:
all_ff = glob2.glob("C:\\top_directory\\**\\**")
If you're running Python 3.4+, you can use the pathlib
module. The Path.glob()
method supports the **
pattern, which means “this directory and all subdirectories, recursively”. It returns a generator yielding Path
objects for all matching files.
from pathlib import Path
configfiles = Path("C:/Users/sam/Desktop/file1/").glob("**/*.txt")
As pointed out by Martijn, glob can only do this through the **
operator introduced in Python 3.5. Since the OP explicitly asked for the glob module, the following will return a lazy evaluation iterator that behaves similarly
import os, glob, itertools
configfiles = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.txt'))
for root, dirs, files in os.walk('C:/Users/sam/Desktop/file1/'))
Note that you can only iterate once over configfiles
in this approach though. If you require a real list of configfiles that can be used in multiple operations you would have to create this explicitly by using list(configfiles)
.
참고URL : https://stackoverflow.com/questions/14798220/how-can-i-search-sub-folders-using-glob-glob-module
'programing' 카테고리의 다른 글
연결 목록을 정렬하는 가장 빠른 알고리즘은 무엇입니까? (0) | 2020.09.07 |
---|---|
애플리케이션 설정에 int [] 배열을 저장하는 방법 (0) | 2020.09.07 |
모든 브라우저에서 하이픈에서 줄 바꿈을 방지하는 방법 (0) | 2020.09.06 |
오디오 및 비디오 컨트롤의 일시 중지 기호에 대한 HTML (0) | 2020.09.06 |
대화 상자에서 뒤로 버튼을 처리하는 방법은 무엇입니까? (0) | 2020.09.06 |