오늘부터 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()
을 사용하는 문제를 어떻게든 해결 해 보고 싶은데 어렵다 ㄱ=