Python 기초

파이썬 기초(22)-디렉토리 관리 프로그램

두설날 2024. 3. 22. 15:56

*이 글을 읽기전에 작성자 개인의견이 있으니, 다른 블로그와 교차로 읽는것을 권장합니다.*

1. 압축파일 정리하기

1-1. pathlib

pathlib은 파일 시스템경로를 다루는 모듈로써, 플랫폼 간에 호환되는 코드를 작성할 수 있으며, 경로를 조작하고 파일 시스템 작업을 수행합니다. path 객체를 사용하여 디렉토리의 생성, 이동, 이름변경, 삭제 등의 작업을 수행합니다.

1-2. extractall

extractall은 zipfile모듈에서 제공하는 메서드 중 하나로,  zip파일의 모든 내용을 특정 디렉토리로 추출합니다.

import os
import glob
import zipfile
import shutil
import fnmatch
import pathlib #폴더 생성, 지정

# 정리 대상 디렉토리 경로 설정하기
target_path = './정리' #경로 변수

# "정리" 디렉토리에서 압축 파일 확인하기
zipfile_path = [] #파일경로 저장
for filename in glob.glob(os.path.join(target_path, '**/*.zip'), recursive=True):
    zipfile_path.append(filename)
print(zipfile_path)

# 압축 파일 해제하기
# for filename in zipfile_path:
#     with zipfile.ZipFile(filename) as myzip:
#         myzip.extractall('압축푸는곳')

for filename in zipfile_path:
    with zipfile.ZipFile(filename) as myzip:
        zipinfo = myzip.infolist()
        # print(zipinfo) 압축파일 정보
        for info in zipinfo: #info 4번 돌기 반복
            decode_name = info.filename.encode('cp437').decode('euc-kr')
            info.filename = os.path.join(target_path, decode_name)
            myzip.extract(info)

2. 파일명 정리하기

2-1. openpyxl

openpyxl은 파이썬으로 엑셀파일과 관련된 작업 수행을 도와주는 모듈입니다. 주로 엑셀파일을 생성하고, 시트에 접근하며, 엑셀파일을 저장하고 출력하는 역할과 관련됩니다. 

!pip install openpyxl
import openpyxl as opx # 엑셀파일 작업 수행하는 모듈
def getFileName(target_path):
    wb = opx.Workbook()
    ws = wb.active 
    ws.cell(row=1, column=1).value = '파일경로'
    ws.cell(row=1, column=2).value = '파일명(변경전)'
    ws.cell(row=1, column=3).value = '파일명(변경후)'
    i = 2
    current_dir = target_path
    filelist = os.listdir(current_dir)
    for filename in filelist:
        ws.cell(row=i, column=1).value = current_dir + '/'
        ws.cell(row=i, column=2).value = filename
        i = i + 1
    wb.save(os.path.join(target_path, 'filelist.xlsx'))
 
getFileName(target_path)

 

3. 파일명 변경하기

# excelRead(경로)의 이름으로 함수를 만들어 아래와 같이 값을 반환하는 만들어보자
# 단, 튜플로 (디렉토리, 변경전파일, 변경후파일) 나열되는 리스트를 반환
# 예) (./정리/	A_2022_07_20_부서로그_인사_004 (1).pdf	A_2022_07_20_부서로그_인사_004.pdf),
# (./정리/	A_2022_01_13_부서로그_인사_002.pdf	A_2022_01_13_부서로그_인사_002.pdf)

def excelRead(filepath):
    wb = opx.load_workbook(filepath)
    ws = wb.active

    dirpath = [r[0].value for r in ws] #1열 변수
    file_before = [r[1].value for r in ws] #2열 변수
    file_after = [r[2].value for r in ws] #3열 변수

    datalist =[] 
    # for i in zip(dirpath, file_before, file_after):
    #     datalist.append(i)
    len_num = len(dirpath)
    for i in range(1, len_num):
            temp_tuple = (dirpath[i], file_before[i], file_after[i])
            datalist.append(temp_tuple)

    
    return datalist
    
rename_list = excelRead(os.path.join(target_path, 'filelist.xlsx'))
print(rename_list)

def fileRename(datalist):
    for data in datalist:
        print(data[1] + '의 파일명을 ' + data[2] + '로 변경합니다')
        shutil.move(data[0]+data[1], data[0]+data[2])
        
fileRename(rename_list)

# 디렉토리안의 파일을 확인하여 카테고리를 뽑아주는 함수를 만들어보자
# ['생산', '클래스설계', '물류', 'ERD', '인사']
# fnmatch.fnmatch() 메서드를 사용
def categoryList(target_path):
    file_list = []
    for filename in os.listdir(target_path):
        # A_2022_01_13_부서로그_인사_002.pdf
        if fnmatch.fnmatch(filename, '*_[0-9][0-9][0-9].*'):
            file_list.append(filename)
    category =[]
    # A_2022_01_13_부서로그_인사_002.pdf
    for file in file_list:
        temp_list=file.split('_') #[A_2022_01_13_부서로그_인사_002.pdf]
        category.append(temp_list[-2])
    category=set(category)
    return list(category)
    
categoryList(target_path)
categorylist = categoryList(target_path) + ['기타']
print(categorylist)

new_path = './new_정리'
def makeDir(new_path, categorylist): #'./new_정리' 폴더 생성 + 
    for category in categorylist:
        new_dir = pathlib.Path(os.path.join(new_path, category))
        # './new_정리' + '/클래스설계', '/물류', '/생산' ..
        # parents: 상위 디렉토리가 없을 경우 상위 디렉토리도 생성
        # exist_ok: 디렉토리가 이미 존재하는 경우 오류를 발생시키지 않도록 함
        new_dir.mkdir(parents=True, exist_ok=True)
makeDir(new_path, categorylist)

4.파일 분류 및 이동하기

def moveFile(new_path, target_path, categorylist):
    dirlist = os.listdir(new_path)
    filelist = os.listdir(target_path)

    categorydic={}

    for file in filelist:
        try:
            temp_list = file.split('_')
            assert temp_list[-2] in categorylist
            categorydic[file] = temp_list[-2] # {'파일명':'분류명'}
        except:
            categorydic[file] ='기타' # {'파일명':'기타'}

    for key, value in categorydic.items():
        shutil.copy(target_path + '/' + key, new_path + '/' + value)
        
moveFile(new_path, target_path, categorylist)