How to Auto Organize Downloads by File Extension in Python
A Python script that sorts files in a directory into subfolders based on their file extensions, creating folders automatically.
Python code
41 linesimport os
import shutil
from pathlib import Path
def organize_downloads(download_dir="~/Downloads"):
"""Move files in a directory into subfolders based on file extension."""
download_path = Path(download_dir).expanduser()
if not download_path.exists():
print(f"Directory not found: {download_path}")
return
for item in download_path.iterdir():
if item.is_file():
ext = item.suffix.lower() or "no_extension"
ext_folder = ext.lstrip(".") + "_files"
target_dir = download_path / ext_folder
target_dir.mkdir(exist_ok=True)
target_path = target_dir / item.name
if not target_path.exists():
shutil.move(str(item), str(target_path))
print(f"Moved: {item.name} -> {ext_folder}/{item.name}")
else:
print(f"Skipped (already exists): {item.name}")
if __name__ == "__main__":
# Example: test with a temporary directory
import tempfile
with tempfile.TemporaryDirectory() as tmp:
p = Path(tmp)
(p / "report.pdf").write_text("PDF content")
(p / "image.png").write_bytes(b"\x89PNG\r\n")
(p / "notes.txt").write_text("Hello")
(p / "README").write_text("No extension")
organize_downloads(tmp)
print("\nOrganized structure:")
for dirpath, dirnames, filenames in os.walk(tmp):
for name in filenames:
print(os.path.relpath(os.path.join(dirpath, name), tmp))
Output
Moved: report.pdf -> pdf_files/report.pdf
Moved: image.png -> png_files/image.png
Moved: notes.txt -> txt_files/notes.txt
Moved: README -> no_extension_files/README
Organized structure:
README
report.pdf
notes.txt
image.png
no_extension_files/README
pdf_files/report.pdf
png_files/image.png
txt_files/notes.txt
How it works
The script uses pathlib.Path for clean path handling and expanduser() to resolve the ~ shortcut. It iterates through files in the target directory, extracts the lowercase file extension, and creates a folder named {extension}_files for each type. Files without an extension are placed in a no_extension_files folder. The shutil.move() function handles the file transfer, and the script skips files that would overwrite existing ones in the destination.
Common mistakes
- Forgetting `.expanduser()` when using `~` in the path, which causes the script to fail with a literal `~` directory
- Not checking if the destination file already exists, which can silently overwrite files with the same name
- Using `os.path` functions instead of `pathlib`, making the code more verbose and harder to read
Variations
- Use `glob` or `os.scandir` for more control when filtering specific file types
- Apply a timestamp prefix to files that already exist to avoid skipping them
Real-world use cases
- Running a scheduled cleanup script that keeps a cluttered downloads folder organized without manual effort.
- Automating file sorting for media folders where photos, videos, and documents arrive from multiple sources.
- Integrating with a file-watcher service that triggers organization whenever new files are added to a shared directory.
Sponsored
More from Automation & scripting
- Aggregate Log Errors Count by Hour in Python easy
- Automate Tweeting New Blog Posts in Python easy
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
Keep learning
Related tutorials and quizzes for this topic.