본문 바로가기
Python

[Python] 여러 폴더의 파일을 날짜별로 분류해보기

by bryan.oh 2022. 1. 17.
반응형

지금 오래된 사진이 여기저기 저장이 되어있습니다.

 

저 하위 폴더 아래에도 또 다른 폴더들이 문어발식으로..

일단 모든 파일들을 가져와서 생성 날짜를 기준으로 년/월 폴더에 나눠서 저장할겁니다.

python3.4 이상부터 사용가능한 pathlib 를 쓰겠습니다.

1. 모든 하위폴더의 파일 가져오기

import os
import pathlib

root_dir = "F:\\사진외장하드"

for path, subdirs, files in os.walk(root_dir):
    for name in files:
        print(pathlib.PurePath(path, name))

실행하면 모든 파일을 전체 경로를 출력합니다.

 

2. 파일을 생성날짜 가져오기

import os
import pathlib
import datetime

root_dir = "F:\\사진외장하드"

for path, subdirs, files in os.walk(root_dir):
    for name in files:
        f = pathlib.Path(path, name)
        creation_time = datetime.datetime.fromtimestamp(f.stat().st_mtime)
        print(creation_time.year, creation_time.month)

년, 월을 찍네요.

st_atime: time of last access
st_mtime: time of last data modification
st_ctime: time of last file status change

 

3. 이제 특정 폴더에 년/월 폴더에 사진을 copy 할겁니다.

(혹~~~시나 코딩 실수로 사진이 날라갈수도 있으니)

copy 는 shutil 을 사용합니다.
import os
import pathlib
import datetime
import shutil

root_dir = "F:\\사진외장하드"
target_dir = "F:\\사진외장하드\\년월별"

for path, subdirs, files in os.walk(root_dir):
    for name in files:
        f = pathlib.Path(path, name)  # 원본 파일
        creation_time = datetime.datetime.fromtimestamp(f.stat().st_mtime)

        # 분류될 경로
        t = pathlib.Path(target_dir, str(creation_time.year), str(creation_time.month))
        t.mkdir(parents=True, exist_ok=True) # 파일 경로에 있는 모든 폴더를 생성함. 있으면 놔둠
        shutil.copy(f, t) # 파일 복사

여기서 아래 코드는 t 경로의 모든 폴더를 생성합니다. (없다면)
os.makedirs() 와 같은 동작을 합니다.

t.mkdir(parents=True, exist_ok=True)

4. 디버그 실행 및 확인

혹시 모르니 디버그로 실행해서 loop 한번만 돌리고 확인해봤습니다.

잘 들어오더군요.

 

근데 폰 백업 폴더도 있어서, 사진이나 동영상 외에 문서 파일도 들어가있더군요 -_-;;

그래서 사진이나 동영상만 복사하도록 확장자로 조건절 추가..

import os
import pathlib
import datetime
import shutil

root_dir = "F:\\사진외장하드"
target_dir = "F:\\사진외장하드\\년월별"
allow_exts = ['.jpg', '.png', '.mov', '.mp4']

for path, subdirs, files in os.walk(root_dir):
    for name in files:
        f = pathlib.Path(path, name)  # 원본 파일
        if f.suffix.lower() in allow_exts:
            creation_time = datetime.datetime.fromtimestamp(f.stat().st_mtime)

            # 분류될 경로
            t = pathlib.Path(target_dir, str(creation_time.year), str(creation_time.month))
            t.mkdir(parents=True, exist_ok=True) # 파일 경로에 있는 모든 폴더를 생성함. 있으면 놔둠
            shutil.copy(f, t) # 파일 복사

 

아, 파일이 많다면 진행상황을 봐야하니까 tqdm 라이브러리를 사용해서 진행상황을 찍어보는게 좋겠네요.

그리고 IO 작업이므로 멀티쓰레드를 쓰면 더 빠른 작업이 되겠네요.

하지만, 전.. 한번만 돌릴 코드라, 이렇게 간단하게 만들어서 돌리겠습니다.

 

참고) tqdm 간단 사용법

일단 pip로 설치

pip install tqdm
import os
import pathlib
import datetime
import shutil
from tqdm import tqdm

root_dir = "F:\\사진외장하드"
target_dir = "F:\\사진외장하드\\년월별"
allow_exts = ['.jpg', '.png', '.mov', '.mp4']

for path, subdirs, files in tqdm(list(os.walk(root_dir))):
    for name in tqdm(files, desc="sub", leave=False):
        f = pathlib.Path(path, name)  # 원본 파일
        if f.suffix.lower() in allow_exts:
            creation_time = datetime.datetime.fromtimestamp(f.stat().st_mtime)

            # 분류될 경로
            t = pathlib.Path(target_dir, str(creation_time.year), str(creation_time.month))
            if not pathlib.Path(t, f.name).exists():
                t.mkdir(parents=True, exist_ok=True) # 파일 경로에 있는 모든 폴더를 생성함. 있으면 놔둠
                shutil.copy(f, t) # 파일 복사

2중 for 문으로 tqdm 을 사용했는데, os.walk 를 바로 사용할 수 없으니 list 로 한번 감싸줬습니다.

진행상황은 보겠지만, 비효율적이고, 파일이 많다면 메모리를 많이 쓰겠죠.

뭐... 그래도 돌려두고 드라마 볼거라.. ㅋ 전 그냥 돌립니다.

 

728x90
반응형

댓글