Skip to content

RENAMING AND MOVING - Using os.rename() and os.replace()

Python
#!/usr/bin/env python3
"""
RENAMING AND MOVING - Using os.rename() and os.replace()
Demonstrates renaming and moving files and directories
"""

import os
import tempfile
import shutil

print("=" * 60)
print("RENAMING AND MOVING FILES - os.rename()")
print("=" * 60)

temp_dir = tempfile.gettempdir()
test_dir = os.path.join(temp_dir, "rename_demo")
os.makedirs(test_dir, exist_ok=True)

print(f"Created test directory: {test_dir}\n")

# Example 1: Basic file rename
print("1. Basic File Rename")
print("-" * 40)
old_name = os.path.join(test_dir, "old_name.txt")
new_name = os.path.join(test_dir, "new_name.txt")

with open(old_name, 'w') as f:
    f.write("Content")

print(f"  Before: {os.path.basename(old_name)} exists = {os.path.exists(old_name)}")
os.rename(old_name, new_name)
print(f"  After:  {os.path.basename(new_name)} exists = {os.path.exists(new_name)}")
print(f"          {os.path.basename(old_name)} exists = {os.path.exists(old_name)}")

# Example 2: Rename directory
print("\n2. Rename Directory")
print("-" * 40)
old_dir = os.path.join(test_dir, "old_dir")
new_dir = os.path.join(test_dir, "new_dir")

os.mkdir(old_dir)
with open(os.path.join(old_dir, "file.txt"), 'w') as f:
    f.write("test")

print(f"  Before: {os.path.basename(old_dir)}/ exists")
os.rename(old_dir, new_dir)
print(f"  After:  {os.path.basename(new_dir)}/ exists")
print("  Contents preserved during rename")

# Example 3: Move file to different directory
print("\n3. Move File to Different Directory")
print("-" * 40)
source_file = os.path.join(test_dir, "source.txt")
dest_dir = os.path.join(test_dir, "destination")
os.makedirs(dest_dir, exist_ok=True)

with open(source_file, 'w') as f:
    f.write("Moving this file")

dest_file = os.path.join(dest_dir, "source.txt")
print(f"  Source: {source_file}")
print(f"  Destination: {dest_file}")

os.rename(source_file, dest_file)
print(f"  File moved successfully")

# Example 4: Rename with different extension
print("\n4. Change File Extension")
print("-" * 40)
txt_file = os.path.join(test_dir, "data.txt")
json_file = os.path.join(test_dir, "data.json")

with open(txt_file, 'w') as f:
    f.write('{"key": "value"}')

print(f"  Before: {os.path.basename(txt_file)}")
os.rename(txt_file, json_file)
print(f"  After:  {os.path.basename(json_file)}")

# Example 5: os.replace() - atomic replacement
print("\n5. os.replace() - Overwrite Existing File")
print("-" * 40)
file1 = os.path.join(test_dir, "file1.txt")
file2 = os.path.join(test_dir, "file2.txt")

with open(file1, 'w') as f:
    f.write("Content 1")
with open(file2, 'w') as f:
    f.write("Content 2")

print("  Before:")
print(f"    file1.txt exists: {os.path.exists(file1)}")
print(f"    file2.txt exists: {os.path.exists(file2)}")

os.replace(file1, file2)
print("  After replace(file1, file2):")
print(f"    file1.txt exists: {os.path.exists(file1)}")
print(f"    file2.txt exists: {os.path.exists(file2)}")

with open(file2, 'r') as f:
    print(f"    file2.txt content: {f.read()}")

# Example 6: Batch rename files
print("\n6. Batch Rename Files")
print("-" * 40)
batch_dir = os.path.join(test_dir, "batch")
os.makedirs(batch_dir, exist_ok=True)

# Create files
for i in range(5):
    filepath = os.path.join(batch_dir, f"temp_{i}.txt")
    with open(filepath, 'w') as f:
        f.write(f"File {i}")

print("  Before:")
for filename in sorted(os.listdir(batch_dir)):
    print(f"    {filename}")

# Rename with new pattern
for filename in os.listdir(batch_dir):
    if filename.startswith("temp_"):
        old_path = os.path.join(batch_dir, filename)
        number = filename.split('_')[1].split('.')[0]
        new_filename = f"file_{number:03s}.txt"
        new_path = os.path.join(batch_dir, new_filename)
        os.rename(old_path, new_path)

print("  After:")
for filename in sorted(os.listdir(batch_dir)):
    print(f"    {filename}")

# Example 7: Case-insensitive rename (safe approach)
print("\n7. Change File Case (Safe)")
print("-" * 40)
lower_file = os.path.join(test_dir, "lowercase.txt")
with open(lower_file, 'w') as f:
    f.write("test")

print(f"  Original: {os.path.basename(lower_file)}")

# Use temporary name first
temp_name = lower_file + ".tmp"
upper_file = os.path.join(test_dir, "LOWERCASE.TXT")

os.rename(lower_file, temp_name)
os.rename(temp_name, upper_file)
print(f"  Renamed:  {os.path.basename(upper_file)}")

# Example 8: Error handling
print("\n8. Error Handling")
print("-" * 40)

# Source doesn't exist
try:
    os.rename("/nonexistent.txt", "/newname.txt")
except FileNotFoundError:
    print("  FileNotFoundError: Source file doesn't exist")

# Destination directory doesn't exist
try:
    test_file = os.path.join(test_dir, "test.txt")
    with open(test_file, 'w') as f:
        f.write("test")
    os.rename(test_file, os.path.join(test_dir, "nonexistent", "test.txt"))
except FileNotFoundError:
    print("  FileNotFoundError: Destination directory doesn't exist")
    os.remove(test_file)

# Example 9: Safe rename function
print("\n9. Safe Rename Function")
print("-" * 40)

def safe_rename(old_path, new_path, overwrite=False):
    """Safely rename file with error handling"""
    try:
        if not os.path.exists(old_path):
            print(f"  Error: Source doesn't exist: {old_path}")
            return False

        if os.path.exists(new_path) and not overwrite:
            print(f"  Error: Destination exists: {new_path}")
            return False

        if overwrite:
            os.replace(old_path, new_path)
        else:
            os.rename(old_path, new_path)

        print(f"  Renamed: {os.path.basename(old_path)} -> {os.path.basename(new_path)}")
        return True

    except Exception as e:
        print(f"  Error: {e}")
        return False

# Test safe rename
test1 = os.path.join(test_dir, "test1.txt")
test2 = os.path.join(test_dir, "test2.txt")
with open(test1, 'w') as f:
    f.write("test")

safe_rename(test1, test2)
safe_rename(test2, os.path.join(test_dir, "test3.txt"))

# Example 10: Move and rename simultaneously
print("\n10. Move and Rename Simultaneously")
print("-" * 40)
source = os.path.join(test_dir, "original.txt")
dest_subdir = os.path.join(test_dir, "archive")
os.makedirs(dest_subdir, exist_ok=True)

with open(source, 'w') as f:
    f.write("Archive this")

destination = os.path.join(dest_subdir, "archived_original.txt")
print(f"  Source: {source}")
print(f"  Dest:   {destination}")

os.rename(source, destination)
print("  Moved and renamed in one operation")

# Cleanup
shutil.rmtree(test_dir)

print("\n" + "=" * 60)
print("Key Points:")
print("  - os.rename() moves/renames files and directories")
print("  - os.replace() overwrites destination if exists")
print("  - Can move across directories")
print("  - Destination directory must exist")
print("  - Atomic operation on same filesystem")
print("=" * 60)