Skip to content

Instantly share code, notes, and snippets.

@kenilt
Created July 24, 2025 14:52
Show Gist options
  • Save kenilt/b7040547eb5e18704190f74b17bc5c1f to your computer and use it in GitHub Desktop.
Save kenilt/b7040547eb5e18704190f74b17bc5c1f to your computer and use it in GitHub Desktop.
Group media files (photos, videos, etc.) into folders by date. This is useful when you have thousands of mixed files exported from phones, cameras, or cloud services.
import os
import shutil
import re
from datetime import datetime
# Set your folder path
folder_path = "path/to/target/folder"
# Date patterns to extract from filenames
patterns = [
r"_(\d{8})_", # _YYYYMMDD_
r"_(\d{8})\d{6}", # _YYYYMMDDHHMMSS
r"(\d{8})_\d{6}" # YYYYMMDD_HHMMSS
]
# === Step 1: Move files to YYYY_MM_DD folders ===
files = os.listdir(folder_path)
for file in files:
file_path = os.path.join(folder_path, file)
if file.startswith("._") or not os.path.isfile(file_path):
continue
# Try extracting date from known patterns
date_str = None
for pattern in patterns:
match = re.search(pattern, file)
if match:
date_str = match.group(1)
break
# Fallback: use last modified date
if not date_str:
mod_time = os.path.getmtime(file_path)
date_str = datetime.fromtimestamp(mod_time).strftime("%Y%m%d")
folder_name = f"{date_str[:4]}_{date_str[4:6]}_{date_str[6:8]}"
folder_full_path = os.path.join(folder_path, folder_name)
os.makedirs(folder_full_path, exist_ok=True)
shutil.move(file_path, os.path.join(folder_full_path, file))
print(f"Moved {file} to {folder_name}/")
# === Step 2: Merge folders with < 3 files into YYYY_MM ===
all_folders = [
f for f in os.listdir(folder_path)
if os.path.isdir(os.path.join(folder_path, f)) and re.match(r"\d{4}_\d{2}_\d{2}", f)
]
all_folders.sort()
for folder in all_folders:
folder_path_full = os.path.join(folder_path, folder)
items = os.listdir(folder_path_full)
if len(items) < 3:
year_month = "_".join(folder.split("_")[:2])
target_folder_path = os.path.join(folder_path, year_month)
os.makedirs(target_folder_path, exist_ok=True)
for item in items:
src = os.path.join(folder_path_full, item)
# 🔐 Skip macOS ghost/metadata files
if item.startswith("._") or not os.path.isfile(src):
continue
dst = os.path.join(target_folder_path, item)
shutil.move(src, dst)
print(f"Merged {item} from {folder}/ into {year_month}/")
os.rmdir(folder_path_full)
print(f"Removed empty folder {folder}/")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment