오늘부터 RPA 수업을 진행한다.
학부생 시절 4학년 1학기에 인공지능 수업을 들었을 때 파일 읽고 쓰고 불러오는 걸 했던 기억이 잠깐 나는데 그때 당시 프로젝트 진행할때 우리가 받은 데이터 파일명에 규칙이 없어서 분류하기가 힘들었다🤔
아무튼 오늘 수업에서 다룬 실습내용을 정리하고자 한다!
os: 운영체제와 관련된 라이브러리shutil: 파일, 폴더와 관련된 라이브러리
os.listdir('폴더경로'): 하위 파일, 폴더 리스트 확인os.path.exists('경로'),os.path.isdir('경로'): 경로 존재 여부 확인 (Boolean값을 가짐.)os.makedirs('경로'): 경로에 맞는 폴더 생성os.remove('경로'): 해당 경로에 있는 파일을 제거
shutil.copyfile('파일경로', '복사할 파일 경로'): 파일복사shutil.rmtree('경로'): 경로 하위 디렉토리와 파일 삭제
TEST_연-월-일_시-분-초.pdf로 만들어져 있습니다.
경로는 위와 같다.

pdf_files에는 이런식으로 TEST_연-월-일_시-분-초.pdf 파일 1000개가 존재한다.
파일 명이 TEST_연-월-일_시-분-초.pdf로 이루어져 있기 때문에
file_list[0].split('_')
<출력>
['TEST', '2019-1-10', '12-21-3.pdf']
.split('_')으로 파일명을 분리할 수 있다. 1번 인덱스가 날짜부분이므로 pdf_date에 그 부분만 따로 저장해서 받아준다.
os.isdir()을 이용하여 폴더가 없으면 (반환 값이 False이면) os.makedirs()를 이용해 폴더를 생성해주는 방식.
import os
import shutil
PDF_DIR = './실습1/pdf_files/'
file_list = os.listdir(PDF_DIR)
pdf_date = []
for file in file_list:
# '_' 기준으로 이름 나누기
temp_list = file.split('_')
# pdf_date에 날짜만 저장
pdf_date.append(temp_list[1])
# 폴더 생성
for i in range(len(pdf_date)):
# 폴더가 없으면(.isdir이 False이면)
if os.path.isdir(PDF_DIR + pdf_date[i]) == False:
os.makedirs(PDF_DIR + pdf_date[i])
# 파일 복사해주기
shutil.copyfile(PDF_DIR + file, PDF_DIR + pdf_date[i] + '/' + file)
코드를 실행하면

이런식으로 폴더가 잘 생성되고 파일도 잘 복사된 것을 확인할 수 있다.
폴더생성시 이미 폴더가 존재하는 경우 에러가 뜨는데
if os.path.isdir(PDF_DIR + folder_name):
pass
# 존재하지 않으면
else:
os.makedirs(PDF_DIR + folder_name)
#폴더 생성
이렇게 if문을 사용해주거나
try:
os.makedirs()
except:
pass
예외처리를 해주면 된다.
다만 내 코드는 이중for문이라서 소요시간이 좀 오래걸림..
이런거 할 때 마다 느끼는데.. 정말 기초가 너무너무너무 중요한 것 같다.
import os
import shutil
PDF_DIR = './pdf_files/'
file_list = os.listdir(PDF_DIR)
for file in file_list:
folder_name = file.split('_')[1]
if os.path.isdir(PDF_DIR + folder_name):
pass
else:
os.makedirs(PDF_DIR + folder_name)
original_dir = PDF_DIR + file
# ./pdf_files/TEST_2019-1-10_12-21-3.pdf
target_dir = PDF_DIR + folder_name + '/' + file
# ./pdf_files/2019-01-10/TEST_2019-1-10_12-21-3.pdf
shutil.move(original_dir, target_dir)
이중for문을 굳이 사용할 필요가 없음.
정규식도 이용할 수 있다고 하셨다. 아래와 같이..
import re
re.search('(?<=\_)[^_]*(?=\_)', file.group())
근데 사실 이거보단 .split()써주는게 훨씬 쉽고 간단한 것 같다.
나뉘어진 폴더에 들어간 파일들을 다시 꺼내오는 것을 해보라고 하셨다.
import os
import shutil
PDF_DIR = './실습1/pdf_files/'
file_list = os.listdir(PDF_DIR)
for file in file_list:
new_list = os.listdir(PDF_DIR + file)
# print(new_list)
if os.path.isdir(PDF_DIR + file):
pdfs = os.listdir(PDF_DIR + file)
for pdf in pdfs:
shutil.move(PDF_DIR + file + '/' + pdf, PDF_DIR + pdf)
음?
이제보니 new_list는 필요가 없다..🤔
각 폴더별로 파일들이 잘 있는지 확인하기 위해서 for문안에 적어준건데 남아있네🤷♀️
어쨌든! 코드 설명을 하자면 shutil.move()를 사용해줬기 때문에 pdf_files에는 날짜별로 정리된 폴더들만 남아있다.
os.path.isdir()을 이용해줘서 해당 폴더 안에 파일이 있다면 그 파일들을 변수 pdfs에 저장한다. 이후 마찬가지로 shutil.move()를 사용해서 각 날짜별 폴더 안에서 밖으로 옮겨주면 끝.
근데 반복문 안에서 os.rmdir()을 이용하여 폴더들을 지워주려고 하니까 자꾸 프로세스 충돌이 떠서 결국 코드에서 빼줬다..
그래서 직접 지워주려고 해도 사용중인 폴더라며 삭제가 불가능하길래 resmon.exe로 프로세스 강제 종료하고 지워주기를 반복했음. (근데 이 경우 커널을 다시시작하면 해결이 됨.. 여러번 파일을 만들었다 지우면 충돌이 일어나나 봄🤔)
그렇다고 반복문 밖에서 사용하면 디렉토리가 비어있지 않아서 못 씀.
근데 또!! 절대경로로는 되는데 상대경로로 안되는 경우가 있었다. (+이 경우도 커널을 다시 시작하니까 해결이 됐다..)
왜 자꾸 이런 오류가 뜨는진 모르겠지만.. 여러번 파일을 지웠다 옮겼다 만들었다 개지랄을해서 그런가보다..라고 생각하기로 함.
os.rmdir()을 사용하는 문제를 어떻게든 해결 해 보고 싶은데 어렵다 ㄱ=