自從拿到相機後一直有個困擾,每次出門拍了很多照片,回來後除了初步挑選照片,將拍壞的照片刪除之外,再來就是將照片依照自己想要的方式歸檔。
平時拍照我都是拍攝RAW+JPG兩種格式的檔案,而相機拍攝完成存入記憶卡都是將這兩種格式放在同一個資料夾,回來後初步挑選完照片還要先分類出RAW檔與JPG檔,接著按照個人習慣年、月、日來分類照片......,每次回來的分類就要做一大堆步驟,有一天突然想著要是電腦可以自動幫我完成就好了,於是這隻小程式就誕生了。
我說的分類格式大概就像是下面這種檔案結構:
D:\Photo>tree /F
D:.
├─2022
└─2023
├─07
│ └─23
│ ├─jpg
│ │ 123.JPG
│ │
│ └─raf
│ 222.raf
└─09
├─16
│ ├─jpg
│ │ 1.JPG
│ │ 2.JPG
│ │
│ └─raf
│ 1.RAF
│ 2.RAF
│
└─24
├─jpg
│ 20230924.JPG
│
└─raf
20230924.RAF
這樣以後要找照片就會很方便,整整齊齊看的也開心,但是如果是手動的話,要新增好多個資料夾,最後還得自己移動照片到對應資料夾,實在太花時間了。所以才想說做個簡單的小程式來幫我處理這些動作,接著就稍微講解一下。
首先,導入我們需要的模組:
import os
import shutil
from pathlib import Path
from datetime import datetime
from tkinter import filedialog
都是一些Python本來就內建的模組,不需要額外安裝。os
用來抓取檔案最後修改時間的timestamp,就是依據這個來建立年月日階層資料夾;shutil
進行檔案的移動;pathlib
來操作路徑;利用datetime
的fromtimestamp
函數來將os
所抓取到的最後修改時間的timestamp轉換成日期物件;最後導入tkinter
的filedialog
函數來讓我們可以選擇指定的資料夾。
導入完模組後,接著讓我們寫一個移動檔案的函數:
# 將文件按照修改日期分類並移動到目標資料夾的函數
def categorize_files(file_list, dest_folder, file_extension):
count = 0
for file in file_list:
modification_time = datetime.fromtimestamp(os.path.getmtime(file))
year = modification_time.year
month = modification_time.month
day = modification_time.day
# 創建目標資料夾的路徑,按照年月日層級
file_path = dest_folder / str(year) / str(month).zfill(2) / str(day).zfill(2) / file_extension
if not file_path.exists():
file_path.mkdir(parents=True)
# 移動文件到目標路徑
shutil.move(file, file_path / file.name)
count += 1
return count
接下來這段就是我們的主要函數啦,
def main(source_dir, target_dir, extensions):
dir1, dir2 = source_dir, target_dir
if not dir1 or not dir2 or not extensions:
print("請指定來源資料夾、目標資料夾和至少一個副檔名。")
return
# 遍歷選定的副檔名列表
for ext in extensions:
file_extension = ext.lower()
path1, path2 = Path(dir1), Path(dir2)
# 獲取來源資料夾中符合副檔名的文件列表
file_list = list(path1.glob(f'*.{file_extension}'))
if not file_list:
print(f"未找到{file_extension}格式的文件,請重新輸入正確的選擇。")
continue
# 調用categorize_files函數,將文件按照修改日期分類並移動到目標資料夾
count = categorize_files(file_list, path2, file_extension)
print(f"完成!!一共有 {count} 個{file_extension}格式的文件被移動")
if __name__ == "__main__":
source_dir = filedialog.askdirectory(title="選擇來源資料夾")
target_dir = filedialog.askdirectory(title="選擇目標資料夾")
extensions = input("請輸入要移動的副檔名,用空格分隔:").split()
main(source_dir, target_dir, extensions)
執行的時候就會跳出要請我們選擇資料夾的畫面,只要選擇需要分類的資料夾
,與想移動到的資料夾
以及輸入想移動的附檔名
,程式就會自動按照檔案的最後修改日期來進行年月日階層的建立資料夾與移動檔案,並在最後告訴你總共有幾個檔案被移動,是不是很方便!
後續我也利用了tkinter
建出一個簡單的GUI介面方便使用,相比上面那段程式,也不用自己打副檔名了,滑鼠點點就可以操作,也能夠新增或移除預設的副檔名!雖然樣貌有點陽春,但功能還是有的!
改天再來分享一下如何製作GUI出來。