Python
File Renaming
Programming
Python Tips
File Management

How to rename a file using Python

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

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

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.