Automate Boring Tasks with Python: 10 Scripts
Ten automation scripts built only on Python's standard library: rename files with a preview, find duplicates by content, merge monthly CSV exports, clear out stale downloads, archive logs, check links, pull email addresses from text, and schedule the lot to run on its own.
GloryTecks Team
Training & Placement Faculty
Last updated: 24 September 2026
A task is worth automating when you do it often, it follows the same steps each time, and a mistake in it is annoying rather than catastrophic. Renaming a folder of photos, merging this month's exports, clearing out the downloads folder: each takes ten minutes by hand and ten lines of Python. The ten scripts below use only the standard library, so there is nothing to install.
Every script that changes files follows one rule: print what it would do first, and only act when you pass a flag. A dry run costs nothing and catches the bug that renames all 400 files to the same name.
1. Rename a folder of files, with a preview
Camera and scanner files arrive as IMG_0001.jpg, IMG_0002.jpg and so on. This script gives them a meaningful prefix and a clean sequence number, in name order:
from pathlib import Path
def bulk_rename(folder: str, prefix: str, apply: bool = False) -> None:
files = sorted(Path(folder).glob("IMG_*.jpg"))
for n, path in enumerate(files, start=1):
target = path.with_name(f"{prefix}-{n:03d}{path.suffix.lower()}")
print(f"{path.name} -> {target.name}")
if apply:
path.rename(target)
bulk_rename("photos", "2026-09-goa-trip") # preview onlyIMG_0001.jpg -> 2026-09-goa-trip-001.jpg
IMG_0002.jpg -> 2026-09-goa-trip-002.jpg
IMG_0003.jpg -> 2026-09-goa-trip-003.jpgRun it again with apply=True once the preview looks right. sorted() matters: glob returns files in whatever order the file system lists them (Python docs: pathlib).
2. Find duplicate files by content
Names lie; contents do not. Group files by size first (files of different sizes cannot be identical), then hash only the candidates:
import hashlib
from collections import defaultdict
from pathlib import Path
def find_duplicates(folder: str) -> list[list[str]]:
by_size = defaultdict(list)
for p in Path(folder).rglob("*"):
if p.is_file():
by_size[p.stat().st_size].append(p)
by_hash = defaultdict(list)
for same_size in by_size.values():
if len(same_size) < 2:
continue
for p in same_size:
with open(p, "rb") as f:
by_hash[hashlib.file_digest(f, "sha256").hexdigest()].append(p.name)
return [sorted(names) for names in by_hash.values() if len(names) > 1]
print(find_duplicates("downloads"))[['report (1).pdf', 'report.pdf']]hashlib.file_digest() reads the file in chunks, so it works on large files too; it needs Python 3.11 or later (Python docs: hashlib). The script only reports. Deleting is a decision you make after reading the list.
3. Merge monthly CSV exports into one file
Many systems export one CSV per month. Combining them by hand invites copy-paste errors; this script stacks them and records which file each row came from:
import csv
from pathlib import Path
def merge_csvs(folder: str, out_file: str) -> int:
rows = []
for path in sorted(Path(folder).glob("sales-*.csv")):
with open(path, newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
rows.append({**row, "source_file": path.name})
with open(out_file, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["region", "amount", "source_file"])
writer.writeheader()
writer.writerows(rows)
return len(rows)
print(merge_csvs("exports", "sales-all.csv"), "rows written")4 rows writtenAlways open CSV files with newline="", as the csv module documentation requires; otherwise quoted fields containing line breaks are misread, and Windows gains blank lines between rows. If the exports might not share the same columns, check each file's header before appending.
4. Clear out files you have not touched in months
import time
from pathlib import Path
def stale_files(folder: str, days: int) -> list[str]:
cutoff = time.time() - days * 86_400
return sorted(p.name for p in Path(folder).iterdir()
if p.is_file() and p.stat().st_mtime < cutoff)
print(stale_files("downloads", 30))['old-installer.exe', 'old-video.mp4']st_mtime is the last modification time. Review the list, then move the files to a holding folder rather than deleting them outright; empty that folder a month later.
5. Archive last month's logs
import shutil
archive = shutil.make_archive("logs-2026-08", "zip", root_dir="logs")
print(archive.endswith("logs-2026-08.zip"))Truemake_archive builds a zip (or tar) of a whole folder in one call and returns the archive's path (Python docs: shutil). Delete the originals only after checking the archive opens.
6. Pull every email address out of a pile of text files
import re
from pathlib import Path
EMAIL = re.compile(r"[\w.+-]+@[\w-]+(?:\.[\w-]+)+")
found = set()
for p in Path("inbox").glob("*.txt"):
found.update(m.lower() for m in EMAIL.findall(p.read_text(encoding="utf-8")))
print(sorted(found))['asha@example.com', 'ravi.k@example.co.in', 'sales@example.org']Lower-casing before adding to the set merges ASHA@example.com with asha@example.com. The pattern is deliberately practical rather than a full implementation of the email address standard. For more patterns, see regular expressions in Python.
7. Check a list of links
import urllib.error
import urllib.request
def check(url: str) -> int:
request = urllib.request.Request(url, method="HEAD", headers={"User-Agent": "link-check"})
try:
with urllib.request.urlopen(request, timeout=10) as response:
return response.status
except urllib.error.HTTPError as err:
return err.code
for url in ["https://docs.python.org/3/", "https://docs.python.org/3/no-such-page"]:
print(check(url), url)A HEAD request asks for the status without downloading the page. Some servers reject HEAD; if one returns 405, retry that URL with GET. Run it weekly against the links in your documentation or bookmarks, and fix whatever is no longer 200.
8 to 10: report, schedule, log
8. Email yourself the result. Build the message with email.message.EmailMessage, attach the merged CSV, and send it with smtplib.SMTP_SSL and send_message() (Python docs: smtplib). Read the password from an environment variable, never from the script. Most mail providers require an app-specific password for this; see environment variables and secrets in Python apps.
9. Run it on a schedule. On Linux or macOS, one cron line runs a script every Monday at 08:00:
0 8 * * 1 /usr/bin/python3 /home/you/scripts/merge_exports.py >> /home/you/scripts/merge.log 2>&1On Windows, Task Scheduler does the same; from a terminal: schtasks /Create /SC WEEKLY /D MON /ST 08:00 /TN MergeExports /TR "py C:\scripts\merge_exports.py". Use absolute paths, because a scheduled job does not start in your usual folder.
10. Make it tell you what happened. A script that runs unattended needs a log: what it did, what it skipped, and the error if it failed. Replace print with the logging module and write to a file. Python logging: a practical setup shows a configuration that suits small scripts.
When one file out of five hundred is broken
A script that stops at the first bad file leaves the job half done, and one that silently skips it hides a problem. The middle path is to handle each item on its own, carry on, and report at the end:
- Wrap the work for one file in
try/except, catching the specific errors you expect, such asUnicodeDecodeErrorfor a file in the wrong encoding orKeyErrorfor a CSV missing a column. - Count successes and failures, and keep the names of the failures.
- Move files that failed into a
needs-attention/folder instead of deleting or ignoring them. - Finish with one summary line, such as "merged 498 files, 2 moved to needs-attention", and exit with a non-zero status if anything failed, so a scheduler can flag the run.
This turns a crash at 3 a.m. into a short list you can deal with over coffee. The same pattern, applied to exceptions in general, is covered in error handling in Python.
Before you automate anything else
- Keep a copy of the input, at least the first few times the script runs for real.
- Write down how long the manual task takes and how often you do it. A script that saves ten minutes every week repays an afternoon of writing within a few months; a two-minute chore you do once a year rarely does.
- Make the script safe to run twice: a second run should do nothing, or the same thing again, never double it.
- Put the paths and settings at the top of the file, or in arguments, instead of scattered through the code. Building a CLI tool with argparse turns a script like these into a proper command.
Looking for something to build rather than something to automate? The Python projects for beginners list has fifteen ideas. File handling, CSV work and automation scripts are all part of the Python Programming course.
Sources
- pathlib β Object-oriented filesystem paths β Python documentation
- hashlib β Secure hashes and message digests β Python documentation
- csv β CSV File Reading and Writing β Python documentation
- shutil β High-level file operations β Python documentation
- smtplib β SMTP protocol client β Python documentation
GloryTecks Team
Training & Placement Faculty
The GloryTecks faculty team mentors learners across Data Science, AI and Data Engineering, with a focus on real-time projects and placement readiness in Hyderabad.
Want to master Python?
Join GloryTecksβ expert-led Python Programming training in Hyderabad with real-time projects and 100% placement support.
Related articles
Learn Python from Scratch: A Complete 2026 Roadmap
How to learn Python from zero: install a current version (including the new Windows install manager), then work through seven stages, from values and loops to files, virtual environments, classes and tests, each ending with a small program you should be able to write on your own.
Python Interview Questions: Top 50 with Answers
Fifty conceptual Python interview questions with short, precise answers, grouped by topic: basics, types and mutability, data structures, functions and scope, OOP, iterators and decorators, errors and files, and internals, with runnable examples for the ones people most often get wrong.
Python for Data Science: The Essential Libraries
The Python data science stack explained by the job each library does: NumPy for arrays, pandas for tables, Matplotlib and seaborn for charts, SciPy and statsmodels for statistics, scikit-learn for models and Jupyter for exploration, with one runnable example that passes a real dataset through them.