Python
File Renaming
Programming
Python Tips
File Management

How to rename a file using Python

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Python provides two standard ways to rename files: os.rename() and pathlib.Path.rename(). Both change a file's name or move it to a different directory. os.rename() works with string paths and is available in all Python versions. pathlib.Path.rename() provides an object-oriented interface and is available in Python 3.4+. For moving files across filesystems, use shutil.move() since os.rename() fails when source and destination are on different mount points.

Using os.rename()

python
1import os
2
3# Rename a file in the same directory
4os.rename('old_name.txt', 'new_name.txt')
5
6# Rename with full paths
7os.rename('/home/user/old_name.txt', '/home/user/new_name.txt')
8
9# Move to a different directory (same filesystem only)
10os.rename('report.txt', 'archive/report.txt')

os.rename() takes two arguments: the current path and the new path. If the destination already exists, behavior varies by OS — on Unix it silently overwrites, on Windows it raises FileExistsError.

Using pathlib.Path.rename()

python
1from pathlib import Path
2
3# Rename a file
4path = Path('old_name.txt')
5new_path = path.rename('new_name.txt')
6print(new_path)  # new_name.txt
7
8# Rename with parent directory
9path = Path('/home/user/old_name.txt')
10path.rename('/home/user/new_name.txt')
11
12# Using the with_name() helper
13path = Path('document.txt')
14new_path = path.rename(path.with_name('document_v2.txt'))
15
16# Change just the extension
17path = Path('data.csv')
18new_path = path.rename(path.with_suffix('.tsv'))
19print(new_path)  # data.tsv

Path.rename() returns the new Path object (Python 3.8+). with_name() and with_suffix() create new paths based on the original, making renames more readable.

Using shutil.move()

For moving files across filesystems:

python
1import shutil
2
3# Works across different filesystems
4shutil.move('report.txt', '/mnt/backup/report.txt')
5
6# Also works for simple renames
7shutil.move('old.txt', 'new.txt')

shutil.move() falls back to copy-then-delete when os.rename() fails, making it work across mount points, network drives, and different partitions.

Batch Renaming

python
1import os
2from pathlib import Path
3
4# Rename all .txt files to .md
5for path in Path('.').glob('*.txt'):
6    path.rename(path.with_suffix('.md'))
7
8# Add a prefix to all files in a directory
9for path in Path('photos').glob('*.jpg'):
10    new_name = f"vacation_{path.name}"
11    path.rename(path.parent / new_name)
12
13# Sequential numbering
14files = sorted(Path('images').glob('*.png'))
15for i, path in enumerate(files, start=1):
16    new_name = f"image_{i:03d}{path.suffix}"
17    path.rename(path.parent / new_name)
18    # image_001.png, image_002.png, ...

Safe Renaming (Avoid Overwrites)

python
1from pathlib import Path
2
3def safe_rename(source, destination):
4    """Rename without overwriting existing files."""
5    dest = Path(destination)
6    if dest.exists():
7        raise FileExistsError(f"Destination already exists: {dest}")
8    return Path(source).rename(dest)
9
10# Or generate a unique name
11def rename_with_increment(source, destination):
12    dest = Path(destination)
13    stem = dest.stem
14    suffix = dest.suffix
15    counter = 1
16
17    while dest.exists():
18        dest = dest.parent / f"{stem}_{counter}{suffix}"
19        counter += 1
20
21    return Path(source).rename(dest)
22
23# report.txt → report_1.txt → report_2.txt
24rename_with_increment('report.txt', 'archive/report.txt')

Renaming with Regular Expressions

python
1import re
2from pathlib import Path
3
4# Replace spaces with underscores in filenames
5for path in Path('.').glob('*'):
6    if ' ' in path.name:
7        new_name = path.name.replace(' ', '_')
8        path.rename(path.parent / new_name)
9
10# Extract and reformat dates in filenames
11# "Report 2025-01-15.pdf" → "2025-01-15_Report.pdf"
12for path in Path('reports').glob('*.pdf'):
13    match = re.search(r'(\d{4}-\d{2}-\d{2})', path.stem)
14    if match:
15        date = match.group(1)
16        name_without_date = path.stem.replace(date, '').strip()
17        new_name = f"{date}_{name_without_date}{path.suffix}"
18        path.rename(path.parent / new_name)

Error Handling

python
1import os
2from pathlib import Path
3
4def rename_file(old_path, new_path):
5    old = Path(old_path)
6    new = Path(new_path)
7
8    if not old.exists():
9        raise FileNotFoundError(f"Source file not found: {old}")
10
11    if not old.is_file():
12        raise IsADirectoryError(f"Source is not a file: {old}")
13
14    # Create destination directory if needed
15    new.parent.mkdir(parents=True, exist_ok=True)
16
17    try:
18        return old.rename(new)
19    except OSError as e:
20        # Falls back to copy+delete for cross-filesystem moves
21        import shutil
22        shutil.move(str(old), str(new))
23        return new

Common Pitfalls

  • os.rename() fails across filesystems: On Linux/macOS, moving a file to a different mount point with os.rename() raises OSError: [Errno 18] Invalid cross-device link. Use shutil.move() which handles cross-filesystem moves by copying then deleting.
  • Silent overwrite on Unix: On Linux/macOS, os.rename() silently overwrites the destination if it exists. On Windows, it raises FileExistsError. Check Path.exists() before renaming if you want consistent cross-platform behavior.
  • Not creating the destination directory: Renaming to a path in a non-existent directory raises FileNotFoundError. Create the directory first with os.makedirs(dir, exist_ok=True) or Path.mkdir(parents=True, exist_ok=True).
  • Using relative paths in batch operations: When iterating with glob(), the paths are relative to the glob root. Using path.rename('new_name') places the file in the current working directory, not in the file's original directory. Use path.rename(path.parent / 'new_name') to keep it in the same directory.
  • Race conditions with existence checks: Checking if not exists() then renaming has a TOCTOU (time-of-check-to-time-of-use) race condition. Another process may create a file with the same name between the check and the rename. For atomic operations, use os.replace() or handle the exception.

Summary

  • os.rename(old, new) renames or moves files within the same filesystem
  • Path.rename(new) provides the same functionality with an object-oriented API
  • Use Path.with_name() and Path.with_suffix() for clean rename expressions
  • shutil.move() works across filesystems by falling back to copy-then-delete
  • Check for existing destination files to avoid silent overwrites on Unix
  • Use Path.parent / new_name in batch operations to keep files in their original directory

Course illustration
Course illustration

All Rights Reserved.