파이썬을 이용한 파일 자동화 - (2) glob
본문 바로가기
PYTHON/기본 문법

파이썬을 이용한 파일 자동화 - (2) glob

by 공돌이삼촌 2023. 5. 31.
반응형

glob

 

glob(): 사용자가 제시한 조건에 맞는 경로를 가진 파일들의 리스트를 반환하는 함수

폴더 내부에 여러겹의 하위 폴더가 있는 등의 복잡한 구조를 가진 폴더에서도

원하는 파일의 경로를 모두 얻어낼 수 있습니다.

import glob
path_list = glob.glob("파일 및 폴더 경로 조건 제시")

 

경로 조건을 제시하라는 것은 ?, *, ** 을 이용하여 조건을 제시하는 것입니다.

실습 데이터에는 데이터1.txt, 데이터2.txt, 데이터1000.txt 있고 

경로 조건에 따라서 한번 알아보자


 [] 대괄호 안에 있는 문자 중 하나와 정확히 한 글자와 매칭

한글자 중에 1또는2또는3이 들어오는 case


 ? 은 임의의 한 문자를 뜻함(무조건 한 문자가 들어가야함)

? 는 무조건 한 문자 이상 들어가있어야 한다는 것을 조건으로 가지고 있습니다. 

따라서 ????처럼 물음표가 4개라면 4개의 해당하는 데이터1000.txt 파일의 경로만이 불러와집니다.


* 은 경로 구분자( /, \\, \ )를 제외한 임의의 문자열을 뜻함

만약 1~1000까지 있다고 하더라도 모두 불러와집니다.

*를 앞뒤로 써도 가능합니다.

현재 탐색은 하위폴더까지 탐색하지 않는

만약 여러 깊이의 하위폴더 내부까지도 탐색하고 싶다면, recursive=True 매개변수를 전달해야합니다. 

따로 지정해주지 않으면 기본 값으로 recursive=False 가 되어 폴더를 재귀적으로 탐색하지 않습니다.

If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories.


 ** 은 경로 구분자( /, \\, \ )를 포함한 임의의 문자열을 뜻함

 

Shutil 라이브러리

os module과 비슷하지만, os 모듈에 없는 복사 기능이 있습니다.

파일 및 폴더의 이동에 사용되며, 이름을 바꿀 수도 있습니다.
 dst에 해당하는 파일이 이미 존재한다면 덮어씌웁니다.

 os.rename() 함수와 사용 목적이나 방법이 동일하지만 

dst 에 해당하는 파일이 이미 존재할 때 어떤 식으로 처리하는지 차이가 있습니다.
 os.rename() 함수는 파일이 존재할 때 에러를 발생시킵니다.

import shutil
shutil.move('./glob_practice','./mytest')

반면에 지우는 함수는 rmtree

remove tree의 약자로 트리구조의 폴더를 내용물까지 모두 삭제한다는 뜻입니다.

내용물이 있든 없든 무조건 폴더를 지우므로 편리한 때가 있지만 신중한 사용이 필요합니다.

os.rmdir( ) 함수는 폴더 내부에 내용물이 있다면 삭제 불가

shutil.rmtree('./mytest')

복사하는 경우 copy함수를 사용하면 됩니다.

복사와 동시에 파일명 수정도 가능
붙여넣기 하려는 파일이 이미 존재한다면 덮어씌움
 파일만 복사 가능. 폴더 복사 시도시 에러 발생

shutil.copy('7.png', './oh/test/test.png')

그럼 폴더를 복사하고 싶다면 copytree를 사용하면 된다.

붙여넣기 하려는 폴더가 이미 존재한다면 에러 발생(copy( ) 함수와의 차이점)
폴더 내부의 내용물까지 모두 복사됨
폴더만 복사 가능. 파일 복사 시도시 에러 발생
복사와 동시에 폴더명 수정도 가능

shutil.copytree(src, dst)

 

처음부터 모든 것을 외우고 사용하기란 쉽지는 않을 겁니다.

상황에 맞게 ‘~한 상황에서 ~한 차이가 있는 함수가 있었다’는 사실만 기억해놓았다가

실제 코드를 작성할 때 간단한 예시코드를 돌려보고 결과를 확인해가며 사용하시면 됩니다.
구글 검색또한 아주아주 현명한 방법이 될 수 있습니다.

 

 

앞에서 배운 os와 glob을 이용한 5가지의 예제를 살펴봅시다

 

1. glob_project 폴더에 있는 ‘프로젝트1’ 폴더에 있는 모든 파일 및 폴더의 경로를 출력해주세요

import glob , os
cur_dir = os.getcwd()
for file_name in glob.glob('./glob_project/프로젝트1/**/*.*',recursive=True) :
    print(os.path.join(cur_dir,file_name))

2. glob_project 폴더 아래에 있는 ‘프로젝트1’ 폴더에 있는 모든 파일의 경로를 출력해보세요.

단 ‘파일’의 경로만 출력되어야 합니다.

import glob , os
cur_dir = os.getcwd()
for file_name in glob.glob('./glob_project/프로젝트1/**/*.*',recursive=True) :
    print(os.path.join(cur_dir,os.path.dirname(file_name)))

만약 확장자가 없는 파일의 경우 나 폴더에 .이 있는 경우는

이러한 *.* glob 형식이 먹지 않을 것이다.

이런경우 os.path.isfile()를 사용하면 된다.

import glob , os
cur_dir = os.getcwd()
for file_name in glob.glob('./glob_project/프로젝트1/**',recursive=True) :
    if os.path.isfile(file_name):
        print(os.path.join(cur_dir,os.path.dirname(file_name)))

 

3. ‘프로젝트2’ 폴더에 있는 모든 이미지 파일의 확장자를 .jpg 확장자로 변환해주세요.

import glob , os
cur_dir = os.getcwd()

for file_name in glob.glob('./glob_project/프로젝트2/**',recursive=True) :
    if os.path.isfile(file_name):
        if 'png' in file_name :
                modified_file=os.path.splitext(file_name)[0]+".jpg"
                os.rename(file_name,modified_file)

str를 일부를 바꿔주는 replace 함수를 사용해도 된다.

os.rename(file_name,file_name.replace(".jpg",".png"))


4. ‘glob예제’ 폴더 하위에 ‘프로젝트4’ 폴더를 새로 만들어 ‘프로젝트2’의 ‘dir1’, ‘dir2’, ‘dir3’ 으로 나뉜 파일들을 한 곳에 복사해 모아주세요.

import glob , os
import shutil
tar_dir = "./glob_project/프로젝트4"
cur_dir = os.getcwd()
if not os.path.exists(tar_dir):
    os.makedirs(tar_dir)
    print("폴더생성")

for file_name in glob.glob('./glob_project/프로젝트2/**',recursive=True) :
    if os.path.isfile(file_name):
        shutil.copy(file_name, tar_dir)

항상 makedirs로 폴더를 생성하기 전에

os.path.exists를 통해 이미 폴더가 생성되는지 check하고 생성하는게 중요하다.

안그러면 반복된 수행시에 에러를 피할 수 있다.

 


5. ‘프로젝트3’ 폴더 하위에 ‘03모음’ 폴더를 만들어 모든 202203.json 파일을 복사해 모아보세요. 단, 원본 파일은 202203(0).json을 파일명으로, n차 수정 폴더 내부의 파일은 202203(n).json을 파일명으로 하여 파일명 중복을 피하도록 코드를 작성해주세요.

import glob , os
import shutil
tar_dir = "./glob_project/프로젝트3/03모음"
cur_dir = os.getcwd()
if not os.path.exists(tar_dir):
    os.makedirs(tar_dir)
    print("폴더생성")

for file_name in glob.glob('./glob_project/프로젝트3/원본/**/202203.json',recursive=True) :
    if os.path.isfile(file_name):
        shutil.copy(file_name,'.//glob_project//프로젝트3//03모음//202203(0).json')

for file_name in glob.glob('./glob_project/프로젝트3/수정본/**/202203.json',recursive=True) :
    if os.path.isfile(file_name):
        n = file_name.split("\\")[1].replace("차 수정","")
        shutil.copy(file_name,f'.//glob_project//프로젝트3//03모음//202203({n}).json')

 

 

 

 

반응형

댓글