Python에서 Glob으로 파일과 폴더경로 불러오기¶
import glob
폴더 구조는 아래와 같다. data폴더와 파이썬 노트북이 하나 존재한다. data폴더엔 abc.tiff파일하나와 train,test 두개의 폴더가 있다. train,test폴더엔 tiff, json파일이 두개씩 존재한다.
!ls ./ -R
./: data glob.ipynb ./data: abc.tiff test train ./data/test: ccc.json ccc.tiff ddd.json ddd.tiff ./data/train: aaa.json aaa.tiff bbb.json bbb.tiff
현재 폴더에 있는 폴더와 파일의 경로들을 받는다.
glob.glob('./*')
['./glob.ipynb', './data']
glob.glob('*')
['glob.ipynb', 'data']
./data/train의 모든 파일 경로를 받자.
glob.glob('./data/train/*')
['./data/train/bbb.tiff', './data/train/aaa.tiff', './data/train/aaa.json', './data/train/bbb.json']
./data/train에 있는 .json으로 끝나는 파일들을 불러오자.
glob.glob('./data/train/*.json')
['./data/train/aaa.json', './data/train/bbb.json']
data폴더에 있는 폴더와 파일경로를 받자.
glob.glob('./data/*')
['./data/test', './data/abc.tiff', './data/train']
./data/*/* 의 검색결과와 일치하는 파일경로를 모두 받아온다.
glob.glob('./data/*/*')
['./data/test/ccc.tiff', './data/test/ddd.tiff', './data/test/ddd.json', './data/test/ccc.json', './data/train/bbb.tiff', './data/train/aaa.tiff', './data/train/aaa.json', './data/train/bbb.json']
./data/*/a* 의 검색결과와 일치하는 파일경로를 모두 받아온다.
glob.glob('./data/*/a*')
['./data/train/aaa.tiff', './data/train/aaa.json']
**와 recursive=True를 사용하면 폴더 안에 있는 폴더의 파일경로들도 재귀적으로 불러올 수 있다. 그러나 폴더내에 다른 폴더와 파일이 너무 많으면 실행시간이 오래걸릴수도 있으니 조심해서 사용하자.
glob.glob('**/*',recursive=True)
['glob.ipynb', 'data', 'data/test', 'data/abc.tiff', 'data/train', 'data/test/ccc.tiff', 'data/test/ddd.tiff', 'data/test/ddd.json', 'data/test/ccc.json', 'data/train/bbb.tiff', 'data/train/aaa.tiff', 'data/train/aaa.json', 'data/train/bbb.json']
glob.glob('./data/**',recursive=True)
['./data/', './data/test', './data/test/ccc.tiff', './data/test/ddd.tiff', './data/test/ddd.json', './data/test/ccc.json', './data/abc.tiff', './data/train', './data/train/bbb.tiff', './data/train/aaa.tiff', './data/train/aaa.json', './data/train/bbb.json']
맨 뒤에 / 를 붙였더니 폴더이름만 받아졌다.
glob.glob('./data/**/',recursive=True)
['./data/', './data/test/', './data/train/']
glob.glob('./data/**/*.tiff',recursive=True)
['./data/abc.tiff', './data/test/ccc.tiff', './data/test/ddd.tiff', './data/train/bbb.tiff', './data/train/aaa.tiff']
glob.glob('./data/**/*.json',recursive=True)
['./data/test/ddd.json', './data/test/ccc.json', './data/train/aaa.json', './data/train/bbb.json']
glob.glob은 파일경로의 배열을 반환하는데, glob.iglob은 iterator을 반환한다.
path_iter = glob.iglob('./data/**',recursive=True)
for path in path_iter:
print(path)
./data/ ./data/test ./data/test/ccc.tiff ./data/test/ddd.tiff ./data/test/ddd.json ./data/test/ccc.json ./data/abc.tiff ./data/train ./data/train/bbb.tiff ./data/train/aaa.tiff ./data/train/aaa.json ./data/train/bbb.json
glob은 숨김파일은 특별하게 처리해서 실제로 data폴더에 .hidden.txt란 파일이 있었음에도 이 파일의 경로를 알려주지 않았다. glob 검색 패턴에 적절한 위치에 .을 추가하면 숨김파일의 경로들만 받을 수 있다.
!ls ./data -a
. .. abc.tiff .hidden.txt .ipynb_checkpoints test train
glob.glob('./data/*')
['./data/test', './data/abc.tiff', './data/train']
glob.glob('./data/.*')
['./data/.hidden.txt', './data/.ipynb_checkpoints']
itertools의 chain으로 iglob으로 만든 iterator두개를 적절히 연결해주면 특정 폴더의 숨겨지지 않은 폴더,파일의 경로들과 숨겨진 폴더 및 파일드의 경로들을 다 불러올 수 있다.
import itertools
path_iter = itertools.chain(glob.iglob('./data/*'),glob.iglob('./data/.*'))
paths = [x for x in path_iter]
print(paths)
['./data/test', './data/abc.tiff', './data/train', './data/.hidden.txt', './data/.ipynb_checkpoints']
파일 및 폴더의 전체 경로가 아닌 이름과 확장자만 필요할 때가 있다. 그럴땐 os.path.basename을 사용하면 편하다.
import os
names = [os.path.basename(x) for x in glob.glob('./**',recursive=True)]
print(names)
['', 'glob.ipynb', 'data', 'test', 'ccc.tiff', 'ddd.tiff', 'ddd.json', 'ccc.json', 'abc.tiff', 'train', 'bbb.tiff', 'aaa.tiff', 'aaa.json', 'bbb.json']
names = [os.path.basename(x) for x in glob.glob('./data/**/*.tiff',recursive=True)]
print(names)
['abc.tiff', 'ccc.tiff', 'ddd.tiff', 'bbb.tiff', 'aaa.tiff']
glob을 사용하면 폴더와 파일의 경로를 반환해준다. 그러나 폴더가 아닌 파일의 경로만 받고 싶을때고 있다. 그럴땐 os.path.isfile을 쓰자.
paths = [x for x in glob.iglob('./**',recursive=True) if os.path.isfile(x)]
print(paths)
['./glob.ipynb', './data/test/ccc.tiff', './data/test/ddd.tiff', './data/test/ddd.json', './data/test/ccc.json', './data/abc.tiff', './data/train/bbb.tiff', './data/train/aaa.tiff', './data/train/aaa.json', './data/train/bbb.json']
폴더의 경로만 받을 때에도 같은 원리로 할 수 있다.
paths = [x for x in glob.iglob('./**',recursive=True) if os.path.isdir(x)]
print(paths)
['./', './data', './data/test', './data/train']
glob.glob('./**/',recursive=True)
['./', './data/', './data/test/', './data/train/']
검색 패턴을 입력할 때 * 말고도 ?와 숫자범위도 사용할 수 있다. ?는 한 문자에 대응하고 숫자범위는 주어진 숫자범위만큼의 문자들이 대응한다. 숫자범위는 [0-9] 와 같은 꼴로 사용한다. glob에 적절한 검색 패턴을 사용해서 효과적으로 경로들을 불러올 수 있도록 하자. glob과 관련한 파이썬 문서 : https://docs.python.org/3/library/glob.html
'Study > Python' 카테고리의 다른 글
Python에서 AhoCorasick(아호코라식) 알고리즘 구현하기 (0) | 2021.04.17 |
---|---|
Python 문자열(string) 그냥 한번 대충 보기 (0) | 2021.04.14 |
Pytorch Tensor(텐서) 만들기 (0) | 2021.03.23 |
Kaggle에서 Pytorch로 간단한 Mnist 숫자 분류기 만들기 (0) | 2021.03.16 |
Pytorch로 선형 회귀(Linear Regression) 구현하기 (0) | 2021.03.15 |
댓글