Rename Files In A Directory Python

5 min read

Renaming files in a directory using Python is a fundamental skill for developers, data scientists, and system administrators who deal with file management automation. Whether you are organizing a messy download folder, standardizing naming conventions for a dataset, or preparing assets for a deployment pipeline, Python offers strong built-in libraries to handle these tasks efficiently. The primary tools for this operation are the os module and the more modern, object-oriented pathlib module, both of which provide the flexibility to rename single files or process entire directories in batch.

Understanding the Core Modules: os vs pathlib

Before diving into specific code examples, it — worth paying attention to. The os module has been the traditional workhorse for interacting with the operating system. Still, string manipulation of paths can be error-prone across different operating systems (Windows vs. It treats paths as strings, which is familiar to developers coming from C or shell scripting backgrounds. Unix-like systems) That's the part that actually makes a difference..

Introduced in Python 3.4, the pathlib module offers an object-oriented approach. It represents filesystem paths as objects (Path objects) with methods and attributes, making code more readable, cross-platform compatible, and less susceptible to bugs related to path separators or escaping characters. Here's the thing — for modern Python development (3. 6+), pathlib is generally the recommended approach, though os remains perfectly valid and widely used in legacy codebases Nothing fancy..

Basic Single File Renaming

The simplest use case involves changing the name of a specific file. Both modules achieve this with a straightforward function call.

Using os.rename()

The os.In real terms, rename(src, dst) function takes two string arguments: the current path and the new path. If the destination already exists, the behavior differs by platform: on Unix it replaces silently (if permissions allow), while on Windows it raises a FileExistsError.

import os

# Define current and new names
current_name = "old_report.txt"
new_name = "final_report.txt"

try:
    os.rename(current_name, new_name)
    print(f"Successfully renamed '{current_name}' to '{new_name}'")
except FileNotFoundError:
    print(f"Error: The file '{current_name}' does not exist.")
except FileExistsError:
    print(f"Error: A file named '{new_name}' already exists.")
except PermissionError:
    print("Error: Permission denied.

### Using `pathlib.Path.rename()`

With `pathlib`, you create a `Path` object for the source and call the `.rename()` method, passing the destination path (as a string or another `Path` object).

```python
from pathlib import Path

source = Path("old_report.txt")
destination = Path("final_report.txt")

try:
    source.rename(destination)
    print(f"Renamed '{source}' to '{destination}'")
except FileNotFoundError:
    print("Source file not found.")
except FileExistsError:
    print("Destination file already exists.

**Key Takeaway:** Always wrap rename operations in `try-except` blocks. Filesystem operations are inherently prone to runtime errors—missing files, permission issues, or destination conflicts—that will crash your script if unhandled.

## Batch Renaming: Processing Entire Directories

The real power of Python shines when you need to rename files in a directory programmatically. Common scenarios include adding prefixes/suffixes, changing extensions, removing special characters, or enforcing a sequential numbering scheme.

### Iterating with `os.listdir()` or `os.scandir()`

`os.listdir()` returns a list of filenames (strings) in a directory. That said, you must join the directory path with the filename to get the full path. Which means `os. scandir()` is more efficient for large directories as it returns `DirEntry` objects with cached file attributes.

```python
import os

directory = "./data_files"
prefix = "backup_"

# Ensure directory exists
if not os.path.isdir(directory):
    print("Directory not found.")
else:
    for filename in os.listdir(directory):
        # Construct full paths
        src = os.path.join(directory, filename)
        
        # Skip directories, only process files
        if os.path.isfile(src):
            dst = os.path.join(directory, prefix + filename)
            
            try:
                os.rename(src, dst)
                print(f"Renamed: {filename} -> {prefix}{filename}")
            except OSError as e:
                print(f"Failed to rename {filename}: {e}")

Iterating with pathlib.Path.iterdir() or glob()

The pathlib approach is cleaner. Path.Here's the thing — iterdir() yields Path objects for every entry. Still, Path. Here's the thing — glob(pattern) allows filtering (e. Now, g. , only .txt files) using wildcard patterns.

from pathlib import Path

target_dir = Path("./images")
counter = 1

# Process only .jpg files
for file_path in target_dir.glob("*.jpg"):
    if file_path.is_file():
        # Create new name: photo_001.jpg, photo_002.jpg, etc.
        new_name = f"photo_{counter:03d}{file_path.suffix}"
        new_path = file_path.with_name(new_name)
        
        try:
            file_path.rename(new_path)
            print(f"{file_path.name} -> {new_name}")
            counter += 1
        except OSError as e:
            print(f"Error renaming {file_path.name}: {e}")

In the example above, file_path.Here's the thing — suffix preserves the original extension (. jpg), and file_path.In practice, with_name(new_name) constructs a new Path object in the same directory with the updated filename. This is significantly safer and more readable than string concatenation Simple, but easy to overlook..

Advanced Renaming Patterns

Real-world requirements often go beyond simple prefixes. Here are patterns for complex transformations.

1. Changing File Extensions

A common task is converting extensions (e.So g. Day to day, , . jpeg to .jpg, or .Day to day, txt to . csv). Using pathlib, the .with_suffix() method makes this trivial and safe.

from pathlib import Path

for file_path in Path(".jpg
        new_path = file_path.jpeg to .That's why jpeg"):
    if file_path. Think about it: with_suffix(". glob("*.Think about it: "). is_file():
        # Changes suffix from .jpg")
        file_path.

### 2. Sanitizing Filenames (Removing Special Characters)

Files downloaded from the web often contain spaces, parentheses, or unicode characters that cause issues in CLI tools or URLs. You can use regular expressions (`re` module) to clean them.

```python
import re
from pathlib import Path

def sanitize(name: str) -> str:
    # Replace spaces with underscores, remove non-alphanumeric (except dot, underscore, hyphen)
    name = name.replace(" ", "_")
    return re.sub(r'[^\w\.

for file_path in Path("downloads").name:
            file_path.is_file():
        clean_name = sanitize(file_path.Plus, = file_path. iterdir():
    if file_path.name)
        if clean_name !rename(file_path.

### 3. Using Metadata (Timestamps, EXIF) for Naming

For photos or logs, naming files based on creation date creates a natural chronological order. In practice, you can access `st_mtime` (modification time) or `st_ctime` (creation time on Windows, metadata change on Unix) via `. stat()`.

```python
from pathlib import Path
from datetime import datetime

for file_path in Path("photos").glob("*.Now, png"):
    if file_path. is_file():
        # Get modification time
        timestamp = file_path.stat().st_mtime
        dt_object = datetime.

```python
        # Format: 2023-10-27_153022
        timestamp_str = dt_object.strftime("%Y-%m-%d_%H-%M-%S")
        new_name = f"{timestamp_str}_{file_path.stem}{file_path.suffix}"
        new_path = file_path.with_name(new_name)

        # Handle naming collisions by appending a counter
        counter = 1
        while new_path.On top of that, stem}_{counter}{file_path. Day to day, exists():
            new_name = f"{timestamp_str}_{file_path. suffix}"
            new_path = file_path.

        file_path.rename(new_path)

This produces filenames such as 2023-10-27_153022_myphoto.Plus, png, which sort naturally in chronological order. For more precise control, such as reading the actual EXIF creation date from an image, you would typically pair pathlib with a library like Pillow or ExifRead.

Wrapping It All Together

Most real-world renaming scripts combine these techniques into reusable functions. To give you an idea, you might create a helper that accepts a file path, applies a naming strategy, and returns the new path. This keeps the main loop clean and makes the

Just Hit the Blog

New on the Blog

Fits Well With This

Readers Loved These Too

Thank you for reading about Rename Files In A Directory Python. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home