본문 바로가기

Programming/Python

[Python]폴더들의 하위 파일 이동/파일 복사(glob,shutil)

안녕하세요. 잇킹 시도르입니다.

 

개인 사진이나 작업 문서들을 일자별이나 장소별로 폴더를 나누어 관리하시는 분들이 많으실 겁니다. 참고로 저는 일자별로 나누어서 관리하는 걸 좋아하고요

 

때때로 이렇게 분산된 파일들을 하나로 모으는 경우가 필요할 때가 있겠죠? 

그래서 아래와 같이 파일 이동 및 복사를 하는 스크립트를 구현하려고 합니다.

-폴더 내의 하위 파일들만 이동

-특정 파일 타입만 이동

-폴더 내의 파일들 복사

 

※해당 기능들은 glob/shutil 라이브러리를 이용해서 처리하고 있으며, 먼저 환경 및 스크립트를 보겠습니다.

 

<폴더 현황>

 

▲1차 하위는 폴더로만 구성

 

 

 

▲20200311 폴더의 하위 파일 구성

 

 

 

▲20200312 폴더의 하위 파일 구성

 

 

 

▲20200313 폴더의 하위 파일 구성

 

 

 

▲20200314 폴더의 하위 파일 구성

 

 

<전체 스크립트>

import glob
import shutil as sh

class file_processing():
    def __init__(self ,**kwargs):
        if 'path' in kwargs.keys():
            self.path = kwargs['path']
        else:
            self.path = None

    def find_file_path_lv1(self):
        ### 대상 파일 경로 확인 ###
        file_list = glob.glob(path + '/*' )

        print('>>> file list lv1')
        for file in file_list:
            print(file)
        print('=' * 40)   

    def find_file_path(self , **kwargs):
        ### 대상 파일 경로 확인 ###
        if 'type' in kwargs.keys(): # 특정 타입의 파일 경로만
            type = '.' + kwargs['type']
            file_list = glob.glob(path + '/**/*' + type, recursive=True)

        else: # 하위 폴더의 파일 전체
            file_list = glob.glob(path + '/**/*' )

        print('>>> file list')
        for file in file_list:
            print(file)
        print('=' * 40)
        self.file_list =  file_list

    def file_move(self, move_path):
        ### 대상 파일 이동 ###
        for file in self.file_list:
            file_name = file.split('\\')[-1] # file_name = 파일명.type
            sh.move(file ,move_path + '/' + file_name)

        print('file move success.')

    def file_copy(self, copy_path):
        ### 대상 파일 복사 ###
        for file in self.file_list:
            file_name = file.split('\\')[-1] # file_name = 파일명.type
            sh.copy(file ,copy_path)

        print('file copy success.')

if __name__ == '__main__':
    path = 'D:/My_Blog/20200322'
    mv_path = 'D:/My_Blog/merge'

    f = file_processing(path=path ,move_path = mv_path)
    f.find_file_path_lv1()
    f.find_file_path()
    #f.file_move(mv_path)
    f.file_copy(mv_path)

 

<실행결과>

>>> file list lv1
D:/My_Blog/20200322\20200311
D:/My_Blog/20200322\20200312
D:/My_Blog/20200322\20200313
D:/My_Blog/20200322\20200314
========================================
>>> file list
D:/My_Blog/20200322\20200311\11.txt
D:/My_Blog/20200322\20200311\12.txt
D:/My_Blog/20200322\20200311\excel1.xlsx
D:/My_Blog/20200322\20200311\excel2.xlsx
D:/My_Blog/20200322\20200311\picture1.bmp
D:/My_Blog/20200322\20200312\move1.txt
D:/My_Blog/20200322\20200312\move2.txt
D:/My_Blog/20200322\20200313\excel3.xlsx
D:/My_Blog/20200322\20200313\test1.txt
D:/My_Blog/20200322\20200313\test2.txt
D:/My_Blog/20200322\20200313\test3.txt
D:/My_Blog/20200322\20200314\picture4.bmp
D:/My_Blog/20200322\20200314\test14.txt
D:/My_Blog/20200322\20200314\test15.txt
D:/My_Blog/20200322\20200314\test16.txt
========================================
file copy success.

Process finished with exit code 0

 

<merge 폴더>

 

▲최종 폴더

 

 

먼저 스크립트의 file_move/file_copy 함수를 보면 파일의 직접적인 처리는 shutil 라이브러리를 활용했습니다.

shutil.move(원본 경로 포함한 파일명, 이동하려는 경로 + 파일명)

shutil.copy(원본 경로 포함한 파일명, 복사하려는 폴더 경로)

 

이외에도 파일 삭제나 폴더 이동/복사 등의 기능도 모두 이용할 수 있는 라이브러리입니다.

shutil로 인터넷에서 검색해보시면 다양하게 파일과 폴더를 다루는 함수를 확인할 수 있습니다.

 

중요한 건 find_file_path 함수로 원본 파일에서 내가 원하는 대상의 경로를 가져오는 것입니다.

이때 활용한 라이브러리는 glob입니다. 

os.listdir은 파일명만 가져온다면 glob.glob은 파일의 경로까지 직접 가져옵니다. 특히 표현식에 따라 다양하게 하위 폴더 및 파일 리스트를 가져올 수 있습니다. 

 

find_file_path_lv1()

해당 함수는 glob 표현식을 비교하긴 위한 목적으로 find_file_path 함수와 비교해 보면 glob.glob(경로/*)으로 1차 하위 파일을 보여주게 됩니다. 20200311~202020314 폴더만 조회됨을 확인할 수 있습니다.

 

find_file_path()

실제 파일 이동/복사에 활용된 경로를 저장하는 함수입니다. glob.glob(경로/**/*)로 폴더의 하위 파일만 조회하게 되었습니다. 저는 하위 폴더의 파일들을 옮기는 것이 목적이므로 20200311~202020314 폴더의 하위 파일 리스트 만을 가져와야 하기에 해당 표현식을 사용한 거죠. 

 

if문을 통해 해당 함수 호출 시에 type을 넣으면 해당 type의 파일만 merge 폴더로 이동이나 복사를 하게 됩니다. 

f.find_file_path(type='xlsx')로 호출하게 되면 다음과 같은 결과를 가지게 됩니다.

C:\Anaconda3\envs\sidorl\python.exe D:/My_DEV/basic_dev/make_rpa_pkg/file_processing.py
>>> file list lv1
D:/My_Blog/20200322\20200311
D:/My_Blog/20200322\20200312
D:/My_Blog/20200322\20200313
D:/My_Blog/20200322\20200314
========================================
>>> file list
D:/My_Blog/20200322\20200311\excel1.xlsx
D:/My_Blog/20200322\20200311\excel2.xlsx
D:/My_Blog/20200322\20200313\excel3.xlsx
========================================
file copy success.

Process finished with exit code 0

 

▲xlsx 파일만 복사되었음을 확인

 

 

이때의 사용되는 표현식은 glob.glob('경로/**/*.xlsx)입니다. 

 

이처럼 glob.glob() 함수를 통해 다양하게 폴더 내의 파일 경로를 가져올 수 있으며, 이를 활용해 shutil 라이브러리로 파일을 다룰 수 있습니다.

 

이상입니다!!!