새로새록

파이썬 - 폴더관리 예시제들 본문

소프트웨어융합/코드잇 정리.py

파이썬 - 폴더관리 예시제들

류지나 2022. 1. 30. 05:11
파일복사

downloads에 있는 파일은 아래의 조건에 맞게 usb 폴더로 복사해야합니다.

  1. 확장자가 ppt, docx, hwp 인 파일은 usb 디렉토리 아래의 docs 디렉토리로 복사해주세요.
  2. 확장자가 jpg , png, svg인 이미지 파일 중 파일 제목에 'screenshot'이라는 글자가 포함되면 usb 디렉토리 아래의 screenshots 디렉토리로, 아닌 것은 usb 디렉토리 아래의 images 디렉토리로 복사해주세요.
  3. 이외 나머지 파일들은 모두 etc 디렉토리로 복사해주세요.
import os
import shutil

# 파일 확장자
report_ext = [".hwp", ".docx", ".pptx"]
img_ext = [".png", ".jpg", ".svg"]
src_dir = "downloads"
dst_dir = "usb"

for path, dirs, files in os.walk(src_dir):
    for file in files:
        file_path = os.path.join(src_dir, file)
        file_name, file_extension = os.path.splitext(file)

        if file_extension in report_ext:
            new_path = os.path.join(dst_dir, "docs", file)
            shutil.copy(file_path, new_path)
            print("{} -> docs로 복사".format(file))
            
        elif file_extension in img_ext:
            if "screenshot" in file_name:
                new_path = os.path.join(dst_dir, "screenshots", file)
                shutil.copy(file_path, new_path)
                print("{} -> screenshots로 복사".format(file))
            else:
                new_path = os.path.join(dst_dir, "images", file)
                shutil.copy(file_path, new_path)
                print("{} -> images로 복사".format(file))
        else:
            new_path = os.path.join(dst_dir, "etc", file)
            shutil.copy(file_path, new_path)
            print("{} -> etc로 복사".format(file))​

 

폴더이름변경

 

 works 폴더 아래의 폴더들 중 폴더 이름에 있는 "코드잇"을 "codeit"으로 모두 변경해주세요.

더보기

<변경 전>

더보기

방법1

new_name = dir.replace("코드잇", "codeit")
file_path = os.path.join(path, dir)
new_path = os.path.join(path, new_name)
os.rename(file_path, new_path)

방법2

for i in range(1, 5):
os.rename(f'works/{i}Q/코드잇 sales', f'works/{i}Q/codeit sales')

import os

target_path = "works"
for path, dirs, files in os.walk(target_path):
    for dir in dirs:
        if "코드잇" in dir:
            new_name = dir.replace("코드잇", "codeit")

            file_path = os.path.join(path, dir)
            new_path = os.path.join(path, new_name)
            os.rename(file_path, new_path)

# 채점 코드
for contents in os.walk('works'):
    print(contents)
#method(2)

target_path = 'works'
# 이곳에 코드를 작성해주세요.
for path, dirs, files in os.walk(target_path):
    for dir in dirs:
        if '코드잇' in dir:
            for i in range(1, 5):
                os.rename(f'works/{i}Q/코드잇 sales', f'works/{i}Q/codeit sales')

주어진 폴더들 중에서
blacklist에 있는 이름을 가진 폴더를 모두 삭제해 주세요.
더보기
import os
import shutil

blacklist = ["Virus", "Malware", "Worm", "Trojan", "Ransomware", "Spyware"]
target_dir = "data"

for path, dirs, files in os.walk(target_dir):
    for dir in dirs:
        if dir.capitalize() in blacklist:
            dir_path = os.path.join(path, dir)
            shutil.rmtree(dir_path)

# 채점 코드
for contents in os.walk("data"):
    print(contents)

shutil 모듈을 사용해 data 폴더에 있는 파일들을 backup 폴더에 압축하는 프로그램을 만들어 보세요

압축 파일의 이름은 'backup_'과 현재 날짜와 시간을 합쳐서(예: backup_2020-07-31 16:22:15) 형태로 만들어보세요.

import os
import shutil
import time

backup_time = time.strftime("%Y-%m-%d %H:%M:%s")
zip_file_name = "backup_{}".format(backup_time)
dst_path = os.path.join("backup", zip_file_name)

shutil.make_archive(dst_path, "zip", "data")

# 채점 코드
zip_file_path = os.path.join("backup", os.listdir("backup")[0])
print(os.path.getsize(zip_file_path))

 

실습과제

이번에는 백업을 복구해주는 타임머신 프로그램을 작성해봅시다. backup 폴더에는 시간대 별로 기존의 파일을 백업해둔 압축 파일이 있습니다. 사용자가 backup_num 변수에 원하는 버전을 넣으면 그에 따라 원하는 버전으로 복구시키는 프로그램을 만들어보세요.

프로그램은 아래와 같은 절차로 이루어 집니다.

  1. 맨 처음에는 backup 폴더의 모든 복구 파일들을 아래와 같은 포맷으로 출력합니다.
n번 파일: 파일 이름  

(예시) 0번 파일: backup_2021-04-01 07:35:1617553575.zip
  1. 그리고 어떤 복구 파일로 복구가 될 예정인지 알려주는 문구를 출력합니다.
n번 파일: 파일 이름 버전으로 복구됩니다. 

(예시) 0번 파일 : backup_2021-04-01 07:35:1617553575.zip 버전으로 복구됩니다.
  1. 기존의 data 폴더를 삭제하고, 정해진 버전의 압축파일을 data 폴더에 압축 해제합니다.
    이렇게하면 data 디렉토리가 해당 버전으로 복구되겠죠?
  2. 채점을 위해 1번 파일(backup_2021-03-17 09:22:3357668703.zip)로 복구하는 코드를 작성해주세요.

실행 결과

0번 파일: backup_2021-04-01 07:35:1617553575.zip
1번 파일: backup_2021-03-17 09:22:3357668703.zip
2번 파일: backup_2021-04-02 03:14:5827916712.zip
1번 파일: backup_2021-03-17 09:22:3357668703.zip 버전으로 복구됩니다.
 
힌트0/3
해설 보기
과제 해설

이번 실습은 shutil.rmtree()와 shutil.unpack_archive() 함수를 사용하는 실습입니다. 먼저 backup 폴더의 복구 파일들을 출력 형식에 맞게 출력하는 코드를 작성합니다.

import shutil
import os

# 1. 복구용 모든 압축 파일을 출력
count = 0
zip_files = os.listdir("backup")
for zip_file in zip_files:
    print("{}번 파일: {}".format(count, zip_file))  # 출력 포맷
    count += 1

출력 결과

0번 파일: backup_2021-04-01 07:35:1617553575.zip
1번 파일: backup_2021-03-17 09:22:3357668703.zip
2번 파일: backup_2021-04-02 03:14:5827916712.zip

그리고 채점을 위해 backup_num은 1로 설정하고, 이 backup_num에 해당하는 파일을 가져온 zip_files를 이용해서 선택합니다. 리스트 형식이니까 인덱스로 선택하면 되겠죠? 그리고 지금 이 상태는 파일 이름만 가져온 상태이므로 "backup" 폴더 안에 있는 backup_zip 파일로 경로를 만들어 주겠습니다.

import shutil
import os

# 1. 복구용 모든 압축 파일을 출력
count = 0
zip_files = os.listdir("backup")
for zip_file in zip_files:
    print("{}번 파일: {}".format(count, zip_file))  # 출력 포맷
    count += 1

# 2. 복구용 압축 파일 선택
backup_num = 1  # 원하는 백업 번호 지정
backup_zip = zip_files[backup_num]  # 백업 파일 선택
backup_zip_path = os.path.join("backup", backup_zip)

그리고 shutil.rmtree() 함수를 사용해서 data 폴더를 삭제합니다.

import shutil
import os

# 1. 복구용 모든 압축 파일을 출력
count = 0
zip_files = os.listdir("backup")
for zip_file in zip_files:
    print("{}번 파일: {}".format(count, zip_file))  # 출력 포맷
    count += 1

# 2. 복구용 압축 파일 선택
backup_num = 1  # 원하는 백업 번호 지정
backup_zip = zip_files[backup_num]  # 백업 파일 선택
backup_zip_path = os.path.join("backup", backup_zip)


# 3. 기존 폴더 삭제
shutil.rmtree("data")

마지막으로 선택한 복구 파일을 원래 data 폴더가 있던 위치에 압축 해제합니다.

완성 코드

import shutil
import os

# 1. 복구용 모든 압축 파일을 출력
count = 0
zip_files = os.listdir("backup")
for zip_file in zip_files:
    print("{}번 파일: {}".format(count, zip_file))  # 출력 포맷
    count += 1

# 2. 복구용 압축 파일 선택
backup_num = 1  # 원하는 백업 번호 지정
backup_zip = zip_files[backup_num]  # 백업 파일 선택
backup_zip_path = os.path.join("backup", backup_zip)


# 3. 기존 폴더 삭제
shutil.rmtree("data")

# 4. zip 파일을 이용해서 파일 복구
print("{}번 파일: {} 버전으로 복구됩니다.".format(backup_num, backup_zip))
shutil.unpack_archive(backup_zip_path, "data")

# 채점 코드
print("\ndata dirs")
for contents in os.walk("data"):
    print(contents)

폴더 내용 가져오기

os.listdir(경로) 를 활용하면 폴더안의 내용을 문자열로 된 리스트로 가져올 수 있습니다.

import os

# data 디렉토리 안의 내용을 문자열로 이루어된 리스트로 모두 가져옵니다.
contents = os.listdir("data")  

print(contents) # <class: list> [ 모든 파일 또는 디렉토리 ]

절대 경로 알아내기

os 모듈의 abspath() 함수를 사용하면 해당 파일 또는 폴더에 대한 절대 경로를 가져올 수 있습니다.

import os

print(os.path.abspath("filename.txt")

경로가 존재하는 경로인지 확인하기

os.path.exists()를 쓰면 해당 경로가 실제로 존재하는 경로인지 확인할 수 있습니다.

import os

print(os.path.exists("data/업무 자동화.png")) # True
print(os.path.exists("data/데이터 사이언스.png")) # False


경로 쉽게 사용하기

os.path.sep

os.path.sep 을 사용하면 내가 사용하는 운영체제가 무엇인지 신경 쓰지 않고 경로 구분 기호를 쓸 수 있습니다. os.path.sep 은 현재 운영체제에서 사용하는 경로 구분 기호로 자동으로 변환됩니다.

import os

print(os.path.sep) # window라면 '\'가 출력되고, macOS라면 '/'가 출력됩니다.

os.path.join

경로를 다루다 보면 폴더가 여러개 중첩되어 있는구조를 자주 만나게 됩니다. 이때 유용하게 쓸 수 있는 것이 os.path.join() 함수인데요. os.path.join은 여러 경로를 합쳐주는 기능을 합니다. 예를 들어, 'Users' 폴더 아래 'Codeit' 폴더 안에 있는'cat.jpg'를 나타내는 경로를 표현하고 싶다면 이렇게 적어주면 됩니다. 경로 구분 기호도 운영체제에 맞게 알아서 인식하기 때문에 경로를 다룰때 조금 더 편하게 사용할 수 있습니다.

import os

file_path = os.path.join('Users', 'Codeit', 'cat.jpg')

print(file_path)
Users\Codeit\cat.jpg # windows
Users/Codeit/cat.jpg # macOS

상대경로의 활용

.은 지금 파이썬 코드가 실행되는 파일과 같은 현재 디렉토리를 의미하고, ..은 현재 워킹 디렉토리의 한 단계 위, 부모 디렉토리를 의미합니다. 예를들어 현재 파이썬 파일이 있는 현재 워킹 디렉토리가 /Users/codeit/automation 라고 하면, . 은 /Users/codeit/automation 을 의미하고, .. 은 현재 워킹 디렉토리의 한 단계 전인 /Users/codeit 까지를 의미하게 됩니다.


모든 폴더 한 번에 살펴보기

폴더 내에 모든 내용을 살펴보기 위해서는 for문과 os.walk()를 사용하면 됩니다. os.walk()의 파라미터로 넘긴 경로 아래에 있는 모든 폴더를 반복하며 반복중인 현재 하위 디렉토리는 path에, 그 경로에 있는 모든 디렉토리는 dirs에, 파일들은 files에 담깁니다.

import os

for path, dirs, files in os.walk("/"):
    print("Path: {}".format(path))
    print("Folders: {}".format(dirs))
    print("Files: {}".format(files))
    print("-----")

파일 이동하기

파일을 이동시키고 싶다면 os.rename 함수를 이용하는 방법과 shutil.move를 이용하는 방법이 있습니다.

os.rename 이용하기

os.rename은 파일의 이름 변경 뿐만 아니라 파일 이동도 할 수 있습니다. os.rename의 두 파라미터에는 파일의 이름이 들어가는 게 아니라, 파일의 경로가 들어갑니다. 아래처럼 이동할 경로를 함께 넣어주면 해당 위치로 이동하게 됩니다.

import os

os.rename("codeit_news.txt", "news/2021_codeit.txt") # macOS
os.rename("codeit_news.txt", "news\\2021_codeit.txt") # windows

이렇게 하면 news 디렉토리 안쪽으로 codeit_news.txt 파일의 이름이 2021_codeit.txt로 바뀌어서 이동하게 됩니다.

shutil.move 이용하기

shutil.move를 이용해도 파일을 이동할 수 있습니다. 사용하는 방법은 os.rename과 똑같습니다.

import shutil

shutil.move("codeit_news.txt", "news/2021_codeit.txt") # macOS
shutil.move("codeit_news.txt", "news\\2021_codeit.txt") # windows

주의 사항

os.rename, shutil.move 모두 파일을 이동할 때 이름이 똑같은 파일이 이미 이동하려는 위치에 존재하면, 이동 시키는 파일로 원래의 파일을 덮어쓰기합니다. 예를 들어, Hello_eng.txt 에는 "Hello"라는 문자열이 있고, Hello_kor.txt 에는 "안녕하세요"가 들어있다고하면

import os
os.rename("Hello_eng.txt", "Hello_kor.txt")
import shutil
shutil.move("Hello_eng.txt", "Hello_kor.txt")

이 두 코드 모두, 실행하면 기존의 Hello_kor 내용인 "안녕하세요"가 삭제됩니다. 이럴 때는, os.path.exists를 사용해서 파일이 실제로 존재하는지 여부를 체크하면 됩니다.

import os
if not os.path.exists("Hello_kor.txt"):
    os.rename("Hello_eng.txt", "Hello_kor.txt")

shutil 모듈

폴더 복사

폴더를 다른 위치로 복사하고 싶다면 shutil 모듈의 copytree() 함수를 사용하면 됩니다. 함수의 이름에서도 알 수 있듯, 복사하는 폴더 안에 다른 폴더가 있는 일종의 '폴더 트리' 형식이어도 모두 한 번에 복사합니다. copytree()의 첫번째 파라미터로 복사 대상 폴더를 넣어주고, 두번째 파라미터로 목적 폴더의 경로를 넣어주면 됩니다. 예를 들어, "data" 폴더 안의 내용을 파일과 폴더 상관없이 모두 "copy_of_data" 폴더로 복사하려면 아래와 같이 하면 됩니다.

import shutil
shutil.copytree("data", "copy_of_data")

내용이 있는 폴더 삭제

내용이 있는 폴더를 삭제하기 위해서는 shutil.rmtree() 함수를 사용하면 됩니다. rmtree() 함수의 파라미터로 삭제할 폴더의 경로를 적어주면 됩니다.

import shutil

shutil.rmtree("폴더 경로")

예를 들어, 내용 유무와 상관없이 test_directory 폴더를 삭제하려면 아래와 같이 하면 됩니다.

import shutil

shutil.rmtree("test_directory")

폴더 압축

폴더 전체를 압축하는 방법을 배워보겠습니다. shutil 모듈의 make_archive() 함수를 사용하면 됩니다. make_archive() 함수의 첫 번째 파라미터로 만들어질 압축 파일의 이름을, 두 번째 파라미터로 압축 방식을, 세 번째 파라미터로는 압축할 폴더의 경로를 넣으면 됩니다.

import shutil

shutil.make_archive("생성되는 압축 파일 이름", "zip", "압축 대상 폴더")

그럼 data 폴더를 압축해볼까요? 파일 이름은 archive, 압축 방식은 zip, 대상 폴더는 "data" 입니다.

import shutil

shutil.make_archive("archive", "zip", "data")

압축 해제

압축 해제하는 방법도 배워볼께요. 압축 해제는 shutil 모듈의 unpack_archive() 함수를 사용하면 됩니다. 첫 번째 파라미터는 압축을 풀 압축 파일 이름을, 두 번째 파라미터는 압축을 해제할 폴더를 적어주면 됩니다. 이전에 코드에서 압축했던 archive.zip 파일을 unpack 폴더에 푼다면 아래처럼 코드를 작성하면 됩니다.

import shutil

shutil.unpack_archive("archive.zip", "unpack")

 


 

 

 

 

 

'소프트웨어융합 > 코드잇 정리.py' 카테고리의 다른 글

html  (0) 2022.02.06
자료구조 - 링크드 리스트 연산들  (0) 2022.02.03
파이썬, 문자열갖고놀기  (0) 2022.01.29
파일다루기 - 출력방식연구  (0) 2022.01.28
셀레니엄 활용예시  (0) 2022.01.20