Every job has a pile of small, boring tasks: renaming files, merging spreadsheets, cleaning up a messy Downloads folder, stitching PDFs together. None of them are hard. They're just tedious, and they eat an hour here and an hour there until a whole afternoon is gone.
The good news is that most of this busywork is a few lines of Python away from never bothering you again. Below are seven small scripts I actually reach for. They use mostly the standard library, so there's very little to install, and each one is short enough to read and understand in a minute.
1. Organize a messy folder by file type
Point this at your Downloads folder and it sorts everything into subfolders by extension.
from pathlib import Path
import shutil
folder = Path.home() / "Downloads"
for file in folder.iterdir():
if file.is_file():
ext = file.suffix.lower().lstrip(".") or "no_extension"
dest = folder / ext
dest.mkdir(exist_ok=True)
shutil.move(str(file), str(dest / file.name))
.pdf files go into a pdf/ folder, .jpg into jpg/, and so on. Run it whenever Downloads gets out of hand.
2. Bulk rename files with a consistent pattern
Camera exports, scanned invoices, screenshots — anything with ugly names. This renames every file in a folder to a clean, zero-padded sequence while keeping the original extension.
from pathlib import Path
folder = Path("./photos")
prefix = "vacation_"
files = sorted(p for p in folder.iterdir() if p.is_file())
for i, file in enumerate(files, start=1):
new_name = f"{prefix}{i:03d}{file.suffix.lower()}"
file.rename(file.with_name(new_name))
You get vacation_001.jpg, vacation_002.jpg, and so on. The :03d keeps them sorting correctly even past 100 files.
3. Merge a stack of CSVs into one
You've got a folder of monthly exports and you want a single file. This concatenates every CSV, keeping the header only once.
import csv
from pathlib import Path
folder = Path("./reports")
out_file = folder / "combined.csv"
csv_files = sorted(folder.glob("*.csv"))
header_written = False
with out_file.open("w", newline="", encoding="utf-8") as out:
writer = csv.writer(out)
for path in csv_files:
with path.open(newline="", encoding="utf-8") as f:
reader = csv.reader(f)
header = next(reader)
if not header_written:
writer.writerow(header)
header_written = True
writer.writerows(reader)
No pandas required. It streams row by row, so it handles files too big to open in Excel.
4. Merge multiple PDFs into one
Combining receipts, contract pages, or chapters. This needs one package: pip install pypdf.
from pathlib import Path
from pypdf import PdfWriter
folder = Path("./pdfs")
writer = PdfWriter()
for pdf in sorted(folder.glob("*.pdf")):
writer.append(str(pdf))
with (folder / "merged.pdf").open("wb") as f:
writer.write(f)
They're merged in filename order, so name them 01_intro.pdf, 02_body.pdf if order matters.
5. Find and remove duplicate files
Duplicates hide everywhere — the same photo saved three times, the same download grabbed twice. This finds true duplicates by hashing file contents (not just matching names).
import hashlib
from pathlib import Path
folder = Path("./cleanup")
def file_hash(path, chunk=8192):
h = hashlib.sha256()
with path.open("rb") as f:
while block := f.read(chunk):
h.update(block)
return h.hexdigest()
seen = {}
for file in folder.rglob("*"):
if file.is_file():
digest = file_hash(file)
if digest in seen:
print(f"Duplicate: {file} (copy of {seen[digest]})")
# file.unlink() # uncomment to actually delete
else:
seen[digest] = file
I always run it once with the delete line commented out, eyeball the list, then uncomment. Hashing content means it catches duplicates even when the filenames differ.
6. Batch-resize images
Shrinking a folder of images for the web or email. Needs pip install pillow.
from pathlib import Path
from PIL import Image
folder = Path("./images")
out = folder / "resized"
out.mkdir(exist_ok=True)
max_width = 1200
for img_path in folder.glob("*.jpg"):
with Image.open(img_path) as img:
if img.width > max_width:
ratio = max_width / img.width
new_size = (max_width, int(img.height * ratio))
img = img.resize(new_size)
img.save(out / img_path.name, quality=85)
It preserves aspect ratio and only shrinks images that are actually too wide.
7. Clean out old files on a schedule
Log folders, temp exports, and caches accumulate forever. This deletes files older than a cutoff.
import time
from pathlib import Path
folder = Path("./logs")
days = 30
cutoff = time.time() - days * 86400
for file in folder.rglob("*"):
if file.is_file() and file.stat().st_mtime < cutoff:
print(f"Deleting {file}")
file.unlink()
Pair it with your OS scheduler (cron on Linux/macOS, Task Scheduler on Windows) and it maintains itself.
The real takeaway
The point isn't any single script — it's the habit. The next time you catch yourself doing the same fiddly thing by hand for the third time, stop and ask: could this be a loop over a folder? Nine times out of ten it can. Start a scripts/ folder, drop these in, and add to it every time busywork shows up. Within a month you'll have a personal toolkit that quietly does an hour of grunt work a day for you.
If you'd rather skip the assembly and start from a set of polished, ready-to-run versions of scripts like these — with error handling, arguments, and sensible defaults already wired in — I packaged nine of them into a Python Automation Toolkit. It's the same spirit as this post, just saved-you-the-typing. Either way, the win is the same: stop doing by hand what a short loop can do for you.
Top comments (0)