태그된 제품에 대해 수수료를 받습니다.
파이썬과 AI를 활용한 윈도우용 리네이머 만들기
회사나 집에서 자유롭게 사용할 수 있는 리네이머를 만들어보려고 합니다.
주로 업무에 필요한 부분은
1. 포토샵으로 레이어를 개별 PNG파일로 내보낸 다음
2. 파일명 앞에 붙은 불필요한 이름(_0000_)들을 수동으로 수정해줄때 리네이머가 필요한데
챗GPT와 파이썬을 활용해서 간단하게 만들어볼 수 있었습니다.
파이썬 윈도우 리네이머 GUI 구현
사용자가 GUI를 통해 디렉토리를 선택하고, 파일 이름에 대한 규칙을 정한 뒤, 미리보기를 통해 확인한 후 파일 이름을 일괄 변경할 수 있도록 구현한 프로그램을 GPT로 생성했습니다.
Tkinter를 사용하여 GUI를 생성하고, 사용자가 입력한 규칙에 따라 파일 이름을 변경하는 프로그램이 간단히 생성되었습니다.
import os
import tkinter as tk
from tkinter import filedialog, messagebox
def rename_files_in_directory(directory, prefix, start_number=1, extension_filter=None):
files = os.listdir(directory)
files = [f for f in files if os.path.isfile(os.path.join(directory, f))]
if extension_filter:
files = [f for f in files if f.endswith(extension_filter)]
for i, filename in enumerate(files):
old_file = os.path.join(directory, filename)
new_file_name = f"{prefix}_{start_number + i}{os.path.splitext(filename)[1]}"
new_file = os.path.join(directory, new_file_name)
os.rename(old_file, new_file)
print(f"Renamed: {old_file} -> {new_file}")
def select_directory():
directory = filedialog.askdirectory()
entry_directory.delete(0, tk.END)
entry_directory.insert(0, directory)
def preview_changes():
directory = entry_directory.get()
prefix = entry_prefix.get()
start_number = int(entry_start_number.get())
extension_filter = entry_extension.get()
if directory and prefix:
files = os.listdir(directory)
files = [f for f in files if os.path.isfile(os.path.join(directory, f))]
if extension_filter:
files = [f for f in files if f.endswith(extension_filter)]
preview_text = ""
for i, filename in enumerate(files):
new_file_name = f"{prefix}_{start_number + i}{os.path.splitext(filename)[1]}"
preview_text += f"{filename} -> {new_file_name}\n"
text_preview.delete(1.0, tk.END)
text_preview.insert(tk.END, preview_text)
else:
messagebox.showwarning("Input Error", "Please provide all required inputs")
def start_renaming():
directory = entry_directory.get()
prefix = entry_prefix.get()
start_number = int(entry_start_number.get())
extension_filter = entry_extension.get()
if directory and prefix:
rename_files_in_directory(directory, prefix, start_number, extension_filter)
messagebox.showinfo("Success", "Files renamed successfully!")
else:
messagebox.showwarning("Input Error", "Please provide all required inputs")
# Tkinter GUI Setup
root = tk.Tk()
root.title("File Renamer")
# Directory selection
tk.Label(root, text="Directory:").grid(row=0, column=0, padx=10, pady=5, sticky='e')
entry_directory = tk.Entry(root, width=40)
entry_directory.grid(row=0, column=1, padx=10, pady=5)
tk.Button(root, text="Browse...", command=select_directory).grid(row=0, column=2, padx=10, pady=5)
# Prefix input
tk.Label(root, text="Prefix:").grid(row=1, column=0, padx=10, pady=5, sticky='e')
entry_prefix = tk.Entry(root, width=40)
entry_prefix.grid(row=1, column=1, padx=10, pady=5)
# Start number input
tk.Label(root, text="Start Number:").grid(row=2, column=0, padx=10, pady=5, sticky='e')
entry_start_number = tk.Entry(root, width=40)
entry_start_number.grid(row=2, column=1, padx=10, pady=5)
entry_start_number.insert(0, "1")
# Extension filter input
tk.Label(root, text="Extension Filter (optional):").grid(row=3, column=0, padx=10, pady=5, sticky='e')
entry_extension = tk.Entry(root, width=40)
entry_extension.grid(row=3, column=1, padx=10, pady=5)
# Preview button
tk.Button(root, text="Preview", command=preview_changes).grid(row=4, column=1, pady=10)
# Text widget for previewing changes
text_preview = tk.Text(root, height=10, width=60)
text_preview.grid(row=5, column=0, columnspan=3, padx=10, pady=10)
# Rename button
tk.Button(root, text="Rename Files", command=start_renaming).grid(row=6, column=1, pady=10)
root.mainloop()
위의 코드로 만든 File Renemer를 실행시켜보았습니다.
기능 설명
Directory : select_directory 함수를 통해 사용자가 리네이밍할 파일들이 있는 디렉토리를 선택할 수 있습니다.
Prefix: 사용자가 입력한 접두어를 모든 파일 이름에 적용합니다.
Start Number: 시작 번호를 입력하여 파일 이름 뒤에 붙일 숫자를 설정합니다.
Extension Filter: 특정 확장자의 파일만 리네이밍할 수 있도록 필터를 적용합니다.
Preview: preview_changes 함수를 통해 변경될 파일 이름을 미리 확인할 수 있습니다.
이 미리보기는 텍스트 위젯에 출력됩니다.
Reneme Files: start_renaming 함수를 통해 실제로 파일 이름을 변경합니다.
변경이 완료되면 성공 메시지가 표시됩니다.
사용 방법
디렉토리 선택: 'Browse...' 버튼을 클릭하여 파일이 있는 디렉토리를 선택합니다.
이름 규칙 입력: Prefix, Start Number, Extension Filter를 설정합니다. Extension Filter는 선택 사항입니다.
미리보기: 'Preview' 버튼을 클릭하여 파일 이름이 어떻게 변경될지 미리 확인합니다.
리네이밍: 'Rename Files' 버튼을 클릭하여 파일 이름을 변경합니다.
테스트하기
임의로 테스트 파일을 생성한 폴더를 디렉토리에 추가한 뒤
Preview와 Rename Files를 클릭했습니다.
그러자 이렇게 정상적으로 동작하는 것을 확인할 수 있었습니다.
Optional 기능 추가하기
그런데 필요한 기능인 파일명 앞자리를 글자수대로 삭제할 수 있는 기능은 생성되지 않았습니다.
그래서 선택 옵션으로 앞의 글자수를 선택한 만큼 삭제할 수 있는 기능을 GPT를 통해 추가해주었습니다.
import os
import tkinter as tk
from tkinter import filedialog, messagebox
def rename_files_in_directory(directory, prefix, start_number=1, extension_filter=None, remove_chars=0):
files = os.listdir(directory)
files = [f for f in files if os.path.isfile(os.path.join(directory, f))]
if extension_filter:
files = [f for f in files if f.endswith(extension_filter)]
for i, filename in enumerate(files):
old_file = os.path.join(directory, filename)
file_name_without_extension = os.path.splitext(filename)[0]
file_extension = os.path.splitext(filename)[1]
# 앞에서 지정한 글자 수만큼 제거
if remove_chars > 0:
file_name_without_extension = file_name_without_extension[remove_chars:]
# 프리픽스와 파일 이름 결합
new_file_name = f"{prefix}_{start_number + i}{file_extension}" if prefix else f"{file_name_without_extension}{file_extension}"
# 만약 글자 제거와 프리픽스를 둘 다 사용할 경우
if remove_chars > 0 and prefix:
new_file_name = f"{prefix}_{file_name_without_extension}{file_extension}"
new_file = os.path.join(directory, new_file_name)
os.rename(old_file, new_file)
print(f"Renamed: {old_file} -> {new_file}")
def select_directory():
directory = filedialog.askdirectory()
entry_directory.delete(0, tk.END)
entry_directory.insert(0, directory)
def preview_changes():
directory = entry_directory.get()
prefix = entry_prefix.get()
start_number = int(entry_start_number.get())
extension_filter = entry_extension.get()
remove_chars = int(entry_remove_chars.get())
if directory:
files = os.listdir(directory)
files = [f for f in files if os.path.isfile(os.path.join(directory, f))]
if extension_filter:
files = [f for f in files if f.endswith(extension_filter)]
preview_text = ""
for i, filename in enumerate(files):
file_name_without_extension = os.path.splitext(filename)[0]
file_extension = os.path.splitext(filename)[1]
if remove_chars > 0:
file_name_without_extension = file_name_without_extension[remove_chars:]
new_file_name = f"{prefix}_{start_number + i}{file_extension}" if prefix else f"{file_name_without_extension}{file_extension}"
if remove_chars > 0 and prefix:
new_file_name = f"{prefix}_{file_name_without_extension}{file_extension}"
preview_text += f"{filename} -> {new_file_name}\n"
text_preview.delete(1.0, tk.END)
text_preview.insert(tk.END, preview_text)
else:
messagebox.showwarning("Input Error", "Please provide the required input")
def start_renaming():
directory = entry_directory.get()
prefix = entry_prefix.get()
start_number = int(entry_start_number.get())
extension_filter = entry_extension.get()
remove_chars = int(entry_remove_chars.get())
if directory:
rename_files_in_directory(directory, prefix, start_number, extension_filter, remove_chars)
messagebox.showinfo("Success", "Files renamed successfully!")
else:
messagebox.showwarning("Input Error", "Please provide the required input")
# Tkinter GUI Setup
root = tk.Tk()
root.title("File Renamer")
# Directory selection
tk.Label(root, text="Directory:").grid(row=0, column=0, padx=10, pady=5, sticky='e')
entry_directory = tk.Entry(root, width=40)
entry_directory.grid(row=0, column=1, padx=10, pady=5)
tk.Button(root, text="Browse...", command=select_directory).grid(row=0, column=2, padx=10, pady=5)
# Prefix input
tk.Label(root, text="Prefix (optional):").grid(row=1, column=0, padx=10, pady=5, sticky='e')
entry_prefix = tk.Entry(root, width=40)
entry_prefix.grid(row=1, column=1, padx=10, pady=5)
# Start number input
tk.Label(root, text="Start Number:").grid(row=2, column=0, padx=10, pady=5, sticky='e')
entry_start_number = tk.Entry(root, width=40)
entry_start_number.grid(row=2, column=1, padx=10, pady=5)
entry_start_number.insert(0, "1")
# Extension filter input
tk.Label(root, text="Extension Filter (optional):").grid(row=3, column=0, padx=10, pady=5, sticky='e')
entry_extension = tk.Entry(root, width=40)
entry_extension.grid(row=3, column=1, padx=10, pady=5)
# Remove characters input
tk.Label(root, text="Remove Characters from Start (optional):").grid(row=4, column=0, padx=10, pady=5, sticky='e')
entry_remove_chars = tk.Entry(root, width=40)
entry_remove_chars.grid(row=4, column=1, padx=10, pady=5)
entry_remove_chars.insert(0, "0")
# Preview button
tk.Button(root, text="Preview", command=preview_changes).grid(row=5, column=1, pady=10)
# Text widget for previewing changes
text_preview = tk.Text(root, height=10, width=60)
text_preview.grid(row=6, column=0, columnspan=3, padx=10, pady=10)
# Rename button
tk.Button(root, text="Rename Files", command=start_renaming).grid(row=7, column=1, pady=10)
root.mainloop()
추가된 기능 설명
프리픽스와 글자 삭제의 선택적 사용: prefix와 remove_chars 모두 선택적으로 사용 가능하며, 사용자가 입력하지 않은 필드는 무시됩니다.
옵션 처리 로직: prefix가 비어 있는 경우, 삭제된 글자 뒤에 별도의 프리픽스 없이 원래 파일 이름이 유지됩니다.
remove_chars만 사용하면 파일 이름의 앞에서 지정한 글자 수만큼 제거되고, 프리픽스는 적용되지 않습니다.
두 옵션을 모두 사용하는 경우, 프리픽스와 삭제된 파일 이름이 결합됩니다.
사용 방법
Prefix 입력 필드와 Remove Characters from Start 필드는 각각 옵션이므로, 사용자가 원하는 방식에 따라 하나 또는 두 개 모두 입력할 수 있습니다.
Preview 버튼을 통해 미리보기를 확인한 후 Rename Files 버튼을 눌러 파일 이름을 변경할 수 있습니다.
실제로 리네이머를 다시 실행한 뒤 .png파일만 필터에 등록하고
Remove Characters from Start에 자리수 6을 입력해주었더니
정상적으로 앞의 불필요한 _0000_ 텍스트가 삭제되는 것을 확인할 수 있었습니다.😀
태그된 제품에 대해 수수료를 받습니다.