본문 바로가기
PROGRAMMING/Python

[PYTHON] 폴더/파일 하위 디렉토리 복사 및 동기화 (os, shutil, sync)

by HYUNHP 2022. 1. 13.
728x90
반응형

안녕하세요, HELLO

이번에는 파이썬을 활용해서 폴더/파일을 복사하는 방법을 공유하고자 합니다.

os 모듈을 활용해서 폴더에 접근하여, shutil를 이용해 폴더/파일을 복사합니다. 그리고 원본 폴더와 복사본 폴더를 비교하여, 누락된 폴더와 파일을 확인하고 최종적으로 폴더 동기화(sync)를 진행합니다. 아래에서 각 절차별로 소스 코드와 함께 설명해보겠습니다.


STEP 1. Import library

STEP 2. 폴더/파일 저장

STEP 3. 폴더/파일 개수 확인

STEP 4. 누락된 폴더/파일 업데이트

STEP 5. 소스코드


STEP 1. Import library

본격적인 실습에 앞서 필요한 라이브러리를 불러오겠습니다. dirsync의 경우는 설치가 안 되어있는 경우, pip install dirsync로 설치해주시기 바랍니다.

 

pip install dirsync

import os
import shutil
from dirsync import sync

 

 


STEP 2. 폴더/파일 저장

'복사할 폴더 위치'와 '저장될 폴더 위치'를 지정해서 파일 저장을 진행합니다. 코드를 진행할 때마다 저장할 폴더/파일을 바꾸기 위해, 파라미터로 지정하며 input 함수를 통해 매번 진행할 때마다 입력합니다.

 

copy_path = str(input('copy_path: ')) # 복사할 폴더 위치
paste_path = str(input('paste_path: ')) # 저장될 폴더 위치

# 원본/복사본 복사 진행
# 기존 작업 폴더가 없는 경우
if not os.path.exists(paste_path):
    shutil.copytree(copy_path, paste_path)
    print('\n복사 완료')
    print('\n----------------------------------------')

 

 
 

실습 폴더

 

os.path.exists("파일/폴더")에서 "파일/폴더" 디렉터리가 없는 경우에 새롭게 디렉터리를 생성합니다. 그리고 shutil.copytree()를 활용해 파일/폴더를 복사합니다. 그러면 아래처럼 성공적으로 폴더/파일이 저장됩니다.

 

원본 폴더/파일(좌) / 복사 폴더/파일(우)

STEP 3. 폴더/파일 개수 확인

이번에는 파일/폴더 일부를 삭제해서, 제대로 복사가 안 된 경우를 확인하고, 누락본을 업데이트하는 방법에 대해서 알아보겠습니다. 우선 원본과 복사본의 폴더와 파일 개수를 살펴보겠습니다. 폴더와 파일 개수는 os.walk()를 활용해서 확인 가능합니다. os.walk()는 하위의 폴더/파일을 반복문 for문으로 탐색 가능합니다. 이를 통해 3개의 튜플(tuple)을 받습니다.

1. root : dir과 files가 있는 path

2. dirs : root 아래에 있는 폴더들

3. files : root 아래에 있는 파일들

이를 활용해, 원본과 복사본의 폴더와 파일 개수를 확인 가능합니다.

 

# 폴더/파일 개수 확인
def file_folder_number():
    path_lst = [copy_path, paste_path]
    # 원본 폴더/파일 개수 설정
    global copy_dir_num
    global copy_file_num
    copy_dir_num = 0
    copy_file_num = 0

    # 복사본 폴더/파일 개수 설정
    global paste_dir_num
    global paste_file_num
    paste_dir_num = 0
    paste_file_num = 0
    
    for i in range(len(path_lst)):
        dir_num = 0
        file_num = 0
    
        for currentdir, dirs, files in os.walk(path_lst[i]):
            for dir_ in dirs :
                dir_num += 1
            for file in files:
                file_num += 1
        if path_lst[i] == copy_path:
            copy_dir_num = dir_num
            copy_file_num = file_num

        elif path_lst[i] == paste_path :
            paste_dir_num = dir_num
            paste_file_num = file_num

        else:
            pass
    
    print('[원본] 폴더 개수: {} / 파일 개수: {}'.format(copy_dir_num, copy_file_num))
    print('\n[복사본] 폴더 개수: {} / 파일 개수: {}'.format(paste_dir_num, paste_file_num))

 

 

원본/복사본 개수 확인

 


STEP 4. 누락된 폴더/파일 업데이트

지금부터는 일부 폴더와 파일을 삭제하고, 누락본을 확인하고 해당 누락 폴더와 파일을 저장하는 법을 살펴보겠습니다.

 

복사본 파일 삭제
# 파일 및 폴더 삭제 진행
file_folder_number()

 

삭제 이후 개수

 

파일 동기화는 sync(확인대상 1, 확인대상2, 'sync')로 가능합니다. 코드를 진행하면 확인대상 1을 바탕으로 확인대상 2의 누락본을 확인하고, 해당 부분을 복사합니다. 그리고 확인 작업을 위해 서로 순서를 바꿔서 한번 더 진행합니다. 이중 확인을 통해 누락되는 부분을 메우게 됩니다.

# 원본/복사본 복사 진행
# 기존 작업 폴더가 없는 경우
if not os.path.exists(paste_path):
    shutil.copytree(copy_path, paste_path)
    print('\n복사 완료')
    print('\n----------------------------------------')
    file_folder_number()

else:
    # 기존에 폴더가 있지만, 파일 개수가 안 맞을 경우
    if copy_dir_num != paste_dir_num:
        print("폴더 개수 안 맞음")
        print('\n[원본] 폴더 개수: {} / 파일 개수: {}'.format(copy_dir_num, paste_dir_num))
        sync(copy_path, paste_path, 'sync') #for syncing one way
        sync(paste_path, copy_path, 'sync') #for syncing the opposite way

    elif copy_file_num != paste_file_num:
        print('파일 개수 안 맞음')
        print('\n[복사본] 폴더 개수: {} / 파일 개수: {}'.format(copy_file_num, paste_file_num))
        sync(copy_path, paste_path, 'sync') #for syncing one way
        sync(paste_path, copy_path, 'sync') #for syncing the opposite way

    else:
        print('개수 일치')

 

그러면 아래와 같은 결과창과 함께, 누락된 폴더와 파일이 정상적으로 저장됩니다.

 

누락된 파일 파악 및 폴더/파일 동기화
최종 결과_원본 = 복사본

STEP 5. 소스코드

최종적으로 아래와 같은 소스 코드가 만들어집니다.

 

import os
import shutil
from dirsync import sync

# 폴더/파일 개수 확인
def file_folder_number():
    path_lst = [copy_path, paste_path]
    # 원본 폴더/파일 개수 설정
    global copy_dir_num
    global copy_file_num
    copy_dir_num = 0
    copy_file_num = 0

    # 복사본 폴더/파일 개수 설정
    global paste_dir_num
    global paste_file_num
    paste_dir_num = 0
    paste_file_num = 0
    
    for i in range(len(path_lst)):
        dir_num = 0
        file_num = 0
    
        for currentdir, dirs, files in os.walk(path_lst[i]):
            for dir_ in dirs :
                dir_num += 1
            for file in files:
                file_num += 1
        if path_lst[i] == copy_path:
            copy_dir_num = dir_num
            copy_file_num = file_num

        elif path_lst[i] == paste_path :
            paste_dir_num = dir_num
            paste_file_num = file_num

        else:
            pass
    
    print('[원본] 폴더 개수: {} / 파일 개수: {}'.format(copy_dir_num, copy_file_num))
    print('\n[복사본] 폴더 개수: {} / 파일 개수: {}'.format(paste_dir_num, paste_file_num))


copy_path = str(input('copy_path: ')) # 복사할 폴더 위치
paste_path = str(input('paste_path: ')) # 저장될 폴더 위치

# 원본/복사본 복사 진행
# 기존 작업 폴더가 없는 경우
if not os.path.exists(paste_path):
    shutil.copytree(copy_path, paste_path)
    print('\n복사 완료')
    print('\n----------------------------------------')
    file_folder_number()

else:
    # 기존에 폴더가 있지만, 파일 개수가 안 맞을 경우
    if copy_dir_num != paste_dir_num:
        print("폴더 개수 안 맞음")
        print('\n[원본] 폴더 개수: {} / 파일 개수: {}'.format(copy_dir_num, paste_dir_num))
        sync(copy_path, paste_path, 'sync') #for syncing one way
        sync(paste_path, copy_path, 'sync') #for syncing the opposite way

    elif copy_file_num != paste_file_num:
        print('파일 개수 안 맞음')
        print('\n[복사본] 폴더 개수: {} / 파일 개수: {}'.format(copy_file_num, paste_file_num))
        sync(copy_path, paste_path, 'sync') #for syncing one way
        sync(paste_path, copy_path, 'sync') #for syncing the opposite way

    else:
        print('개수 일치')

 


■ 마무리

오늘은 파이썬을 활용해서 폴더/파일을 복사하는 방법에 대해서 알아봤습니다.
그럼​ 오늘 하루도 즐거운 나날되셨으면 좋겠습니다

마지막으로 좋아요댓글 부탁드립니다 :)
감사합니다.

반응형

댓글