How to Bulk Rename Hundreds of Website Files Using Python Scripts (Step-by-Step Guide)

Category: AI & Tech Tutorials | Author: Taazamind Editorial Team | Last Updated: June 2025

Manually renaming even 50 files is tedious. Rename 500 of them — images, HTML pages, CSS assets, or media uploads — and you’re looking at hours of error-prone clicking, plus the very real risk of breaking your site’s internal links if one file name ends up with a typo. If you’ve ever exported a batch of product images from Canva, downloaded assets from a stock site, or migrated content between CMS platforms, you already know exactly what this feels like.

The problem usually comes in three forms: files arrive with random hash names (img_8473hf92.jpg), platforms append long query strings to exported filenames, or your server is case-sensitive (Linux) while your old server was not, breaking every URL that depended on uppercase letters. Python solves all three of these cleanly, without needing to install heavy software or use a GUI tool that caps out at 100 files.

This guide covers four distinct Python approaches — from the simplest one-liner script for beginners up to a recursive, pattern-matching renamer with a dry-run safety mode. Every method is tested, beginner-friendly, and completely free.

Technical Specifications

Technical DetailSpecification / Requirement
Target PlatformWindows 10/11, macOS 12+, Ubuntu/Debian Linux
Python Version RequiredPython 3.7 or higher
External Libraries NeededNone for core methods (optional: tqdm for progress bars)
File Types SupportedAny — JPG, PNG, HTML, CSS, JS, PDF, WEBP, etc.
Max Files Tested2,000+ files in a single script run
Difficulty LevelBeginner to Intermediate
Estimated Setup Time5–10 minutes
Risk of Data LossLow — use dry-run preview before renaming

Method 1: Add a Numbered Prefix to Every File in a Folder

This is the most common use case — you have a folder of unsorted images and you want clean names like product-001.jpg, product-002.jpg, and so on. This script handles it in under 15 lines.

  1. Open a text editor (Notepad on Windows, TextEdit on macOS, or nano in terminal) and create a new file called rename_numbered.py.
  2. Paste the following code into the file:
import os

folder = "/path/to/your/files"   # Change this to your actual folder path
prefix = "product"                # Change this to whatever prefix you want
extension = ".jpg"                # Only rename files with this extension

files = sorted([f for f in os.listdir(folder) if f.endswith(extension)])

for index, filename in enumerate(files, start=1):
    new_name = f"{prefix}-{index:03d}{extension}"
    old_path = os.path.join(folder, filename)
    new_path = os.path.join(folder, new_name)
    os.rename(old_path, new_path)
    print(f"Renamed: {filename} → {new_name}")

print(f"\nDone. {len(files)} files renamed.")
  1. Update the folder, prefix, and extension variables to match your actual directory and file type.
  2. Save the file and open your terminal or command prompt.
  3. Navigate to the folder where you saved the script using cd /path/to/script.
  4. Run the script with python rename_numbered.py. You’ll see each rename printed to the terminal in real time.

The :03d format in the f-string is what produces zero-padded numbers (001, 002) instead of bare digits. This matters for file sorting — without padding, 10 sorts before 2 in most file managers.

Method 2: Find and Replace Text Inside File Names

Sometimes you don’t need sequential numbering — you just need to strip or replace a consistent string. For example, changing every file from page-home-v2-FINAL.html to page-home.html, or replacing spaces with hyphens across an entire folder of blog post images.

  1. Create a new file called rename_replace.py.
  2. Paste this script:
import os

folder = "/path/to/your/files"
find_text = " "          # Text to search for in each filename
replace_text = "-"       # What to replace it with

for filename in os.listdir(folder):
    if find_text in filename:
        new_name = filename.replace(find_text, replace_text)
        os.rename(
            os.path.join(folder, filename),
            os.path.join(folder, new_name)
        )
        print(f"{filename} → {new_name}")
  1. Set find_text to the string you want to remove or replace and replace_text to what replaces it. To simply remove a string, set replace_text = "".
  2. Run it the same way as Method 1.

This approach is particularly useful for fixing SEO-unfriendly image names before uploading to WordPress. Spaces in filenames become %20 in URLs, which breaks image embeds in some themes and slows page load validation tools.

Method 3: Bulk Rename with a Dry-Run Preview (Safest Approach)

Before running any mass rename on hundreds of production files, you want to preview every change without actually modifying anything. This version adds a dry_run=True flag that prints the planned renames without touching a single file.

  1. Create a new file called rename_preview.py.
  2. Paste the following:
import os
import re

folder = "/path/to/your/files"
dry_run = True   # Set to False when you're ready to actually rename

def clean_name(filename):
    name, ext = os.path.splitext(filename)
    name = name.lower()                       # Convert to lowercase
    name = re.sub(r'[^a-z0-9\-]', '-', name) # Replace special chars with hyphens
    name = re.sub(r'-+', '-', name)           # Collapse multiple hyphens
    name = name.strip('-')                    # Remove leading/trailing hyphens
    return name + ext.lower()

for filename in os.listdir(folder):
    if os.path.isfile(os.path.join(folder, filename)):
        new_name = clean_name(filename)
        if new_name != filename:
            if dry_run:
                print(f"[PREVIEW] {filename} → {new_name}")
            else:
                os.rename(
                    os.path.join(folder, filename),
                    os.path.join(folder, new_name)
                )
                print(f"[RENAMED] {filename} → {new_name}")

mode = "DRY RUN" if dry_run else "LIVE"
print(f"\n[{mode} COMPLETE]")
  1. Run the script with dry_run = True first. Review every line in the output carefully.
  2. Change dry_run = True to dry_run = False once you’re satisfied with the preview output.
  3. Run the script again to execute the actual renames.

This script also enforces SEO-safe naming conventions automatically — lowercase only, hyphens instead of underscores or special characters, no double-hyphens. If you’re uploading renamed images directly to a WordPress media library or serving them as static assets, this format aligns with Google’s image URL best practices.

Method 4: Recursively Rename Files Inside Nested Subfolders

If your website files are organized into subdirectories — /images/blog/, /images/products/, /images/banners/ — the above scripts only process the top-level folder. This version walks the entire folder tree recursively.

  1. Create rename_recursive.py and paste the following:
import os

root_folder = "/path/to/your/root"
find_text = "_"
replace_text = "-"
target_extension = ".jpg"  # Set to "" to process all file types

renamed_count = 0

for dirpath, dirnames, filenames in os.walk(root_folder):
    for filename in filenames:
        if target_extension and not filename.endswith(target_extension):
            continue
        if find_text in filename:
            new_name = filename.replace(find_text, replace_text)
            old_path = os.path.join(dirpath, filename)
            new_path = os.path.join(dirpath, new_name)
            os.rename(old_path, new_path)
            print(f"{old_path} → {new_path}")
            renamed_count += 1

print(f"\nTotal files renamed: {renamed_count}")
  1. Set root_folder to your top-level directory path.
  2. Adjust find_text, replace_text, and target_extension to match your use case.
  3. Run with python rename_recursive.py.

os.walk() is what makes this recursive — it yields every subdirectory and its files, so you don’t need to loop through each subfolder manually. For a WordPress uploads folder with years of nested /2023/04/, /2024/01/ directories, this handles everything in a single pass.

Frequently Asked Questions

Will renaming files with Python break my WordPress media library links?

Yes, if the files are already attached to WordPress posts and pages, renaming them on disk will break the URLs stored in the database because WordPress stores the absolute path and filename. The safe workflow is to rename files before uploading them to your media library, or to use a WordPress plugin like “Enable Media Replace” or “Regenerate Thumbnails” after renaming and re-uploading. If you’ve already uploaded and need to rename existing media, you’ll need to update the wp_posts and wp_postmeta tables in MySQL as well — a separate process from the file rename itself.

How do I make Python rename files to all lowercase on Windows?

Windows’s file system is case-insensitive, which causes a subtle problem: os.rename("Image.JPG", "image.jpg") appears to do nothing because Windows treats them as the same file. The fix is to rename to a temporary name first, then rename again to the lowercase target. Add this to your script: os.rename(old_path, old_path + "_tmp") followed by os.rename(old_path + "_tmp", new_path). This two-step approach forces Windows to recognize the case change as a real rename.

Can I undo a bulk rename if something goes wrong?

Python’s os.rename() does not create backups automatically, and there is no built-in undo. Before running any live rename script on important files, either copy the entire folder to a backup location first (shutil.copytree(src, dst)) or add logging to your script that writes the original and new names to a CSV file. With that CSV, you can write a simple reversal script that swaps the name columns and renames everything back in seconds.

Published on Taazamind.com | Practical tutorials for developers, webmasters, and digital builders.

Leave a Comment