- shutil.move() — moving files and directories
- Move vs Rename — understanding the difference
- Batch moving — moving multiple files
- Moving directories — relocating entire folders
- Error handling — robust file moving
- Best practices — safe file relocation
Moving Files in Python
Moving files is a common operation when you need to organize files, archive data, or restructure your file system. Python's shutil.move() function provides a simple way to move files and directories from one location to another.
Think of moving a file like taking a file from one folder and placing it in another. The file ends up in the new location and is no longer in the original place. It's different from copying, where the original stays put.
💡 Key concept: Moving a file is different from copying it. When you move a file, it is removed from its original location and appears only in the new location. The shutil.move() function handles this in a single operation.
Using shutil.move()
The Primary Way to Move Files
# The shutil.move() function moves a file or directory
import shutil
import os
# Create a sample file
with open("file_to_move.txt", "w") as f:
f.write("This file will be moved.\n")
f.write("It will no longer be in the original location.\n")
print("Created: file_to_move.txt")
# 1. Basic move
shutil.move("file_to_move.txt", "moved_file.txt")
print("Moved: file_to_move.txt → moved_file.txt")
# 2. Move to a different directory
os.makedirs("target_folder", exist_ok=True)
shutil.move("moved_file.txt", "target_folder/moved_file.txt")
print("Moved: moved_file.txt → target_folder/moved_file.txt")
# 3. Move with a new name
shutil.move("target_folder/moved_file.txt", "target_folder/renamed_file.txt")
print("Moved and renamed: target_folder/moved_file.txt → target_folder/renamed_file.txt")
# 4. Check that the original no longer exists
if not os.path.exists("moved_file.txt"):
print("The original file is gone (as expected)")
# 5. Verify the file is in the new location
if os.path.exists("target_folder/renamed_file.txt"):
print("File is in the new location")
shutil.move() key points:
- Removes original — file no longer exists at source
- Can rename — change name while moving
- Works on directories — can move entire folders
- Overwrites by default — if destination exists
- Cross-platform — works on all operating systems
Quick Check: What happens to the original file when you use shutil.move()? (Answer: It is removed from the original location)
Move vs Rename
Understanding the Difference
# Move and rename are similar but different operations
import shutil
import os
# Create a test file
with open("test_file.txt", "w") as f:
f.write("Testing move vs rename\n")
print("Created: test_file.txt")
# 1. Rename using os.rename() (same directory)
os.rename("test_file.txt", "renamed_file.txt")
print("Renamed: test_file.txt → renamed_file.txt")
# 2. Move using shutil.move() (different directory)
os.makedirs("archive", exist_ok=True)
shutil.move("renamed_file.txt", "archive/archived_file.txt")
print("Moved: renamed_file.txt → archive/archived_file.txt")
# 3. Move and rename in one operation
shutil.move("archive/archived_file.txt", "archive/final_file.txt")
print("Moved and renamed: archive/archived_file.txt → archive/final_file.txt")
# Compare:
# os.rename() - works within the same filesystem
# shutil.move() - works across filesystems and can move directories
# 4. When to use each
# Use os.rename() when:
# - You're just changing the name in the same directory
# - You need to rename directories
# Use shutil.move() when:
# - You're moving between different directories
# - You want to move and rename in one operation
# - You need to move across different filesystems
Move vs Rename comparison:
- os.rename() — simple rename within same directory
- shutil.move() — move to different location, can also rename
- os.rename() is faster — for simple renames
- shutil.move() is more powerful — works across filesystems
Quick Check: When should you use shutil.move() instead of os.rename()? (Answer: When moving between different directories or filesystems)
Moving Multiple Files
Organizing Files in Bulk
import shutil
import os
# Create sample files
for i in range(3):
with open(f"doc_{i}.txt", "w") as f:
f.write(f"Document {i}\n")
print("Created: doc_0.txt, doc_1.txt, doc_2.txt")
# 1. Move all files matching a pattern
def move_matching_files(source_dir, dest_dir, pattern):
"""Move files matching a pattern to a destination"""
os.makedirs(dest_dir, exist_ok=True)
for filename in os.listdir(source_dir):
if pattern in filename and os.path.isfile(os.path.join(source_dir, filename)):
source_path = os.path.join(source_dir, filename)
dest_path = os.path.join(dest_dir, filename)
shutil.move(source_path, dest_path)
print(f"Moved: {filename} → {dest_dir}/")
move_matching_files(".", "documents", "doc_")
# 2. Move files based on extension
def move_by_extension(source_dir, dest_dir, extension):
"""Move files with a specific extension"""
os.makedirs(dest_dir, exist_ok=True)
for filename in os.listdir(source_dir):
if filename.endswith(extension):
source_path = os.path.join(source_dir, filename)
dest_path = os.path.join(dest_dir, filename)
shutil.move(source_path, dest_path)
print(f"Moved: {filename} → {dest_dir}/")
move_by_extension(".", "text_files", ".txt")
# 3. Move files with progress tracking
def move_with_progress(source_dir, dest_dir):
"""Move files with progress indication"""
files = [f for f in os.listdir(source_dir) if os.path.isfile(os.path.join(source_dir, f))]
total = len(files)
os.makedirs(dest_dir, exist_ok=True)
for i, filename in enumerate(files, 1):
source_path = os.path.join(source_dir, filename)
dest_path = os.path.join(dest_dir, filename)
shutil.move(source_path, dest_path)
print(f"Progress: {i}/{total} - Moved: {filename}")
# 4. Move with filtering
def move_filtered_files(source_dir, dest_dir, filter_func):
"""Move files that pass a filter condition"""
os.makedirs(dest_dir, exist_ok=True)
for filename in os.listdir(source_dir):
source_path = os.path.join(source_dir, filename)
if os.path.isfile(source_path) and filter_func(filename):
dest_path = os.path.join(dest_dir, filename)
shutil.move(source_path, dest_path)
print(f"Moved: {filename} → {dest_dir}/")
Batch moving strategies:
- Pattern matching — move files with specific names
- Extension based — move files by file type
- Progress tracking — monitor move operations
- Filtering — use custom conditions
Quick Check: How can you move only files with a specific extension? (Answer: Check filename.endswith(extension))
Moving Directories
Relocating Entire Folders
import shutil
import os
# Create a directory structure
os.makedirs("source_folder/subfolder", exist_ok=True)
with open("source_folder/file1.txt", "w") as f:
f.write("File 1 in source_folder\n")
with open("source_folder/subfolder/file2.txt", "w") as f:
f.write("File 2 in subfolder\n")
print("Created: source_folder/ with files")
# 1. Move an entire directory
shutil.move("source_folder", "destination_folder")
print("Moved: source_folder → destination_folder")
# 2. Verify the directory moved
if os.path.exists("destination_folder"):
print("Directory moved successfully")
print("Contents:", os.listdir("destination_folder"))
# 3. Move directory with overwrite protection
def safe_move_dir(source, destination):
"""Move directory safely with checks"""
if not os.path.exists(source):
print(f"Source '{source}' does not exist")
return False
if os.path.exists(destination):
print(f"Destination '{destination}' already exists")
response = input("Overwrite? (y/n): ")
if response.lower() != 'y':
print("Move cancelled")
return False
shutil.move(source, destination)
print(f"Moved: {source} → {destination}")
return True
# 4. Move directory and verify
def move_and_verify(source, destination):
"""Move directory and verify it worked"""
try:
shutil.move(source, destination)
if not os.path.exists(source):
print(f"Source '{source}' no longer exists")
if os.path.exists(destination):
print(f"Destination '{destination}' exists")
return True
return False
except Exception as e:
print(f"Error: {e}")
return False
Directory moving key points:
- Moves all contents — entire directory and subdirectories
- Removes source — original directory is gone
- Can move across drives — works across filesystems
- Handle conflicts — destination may already exist
Quick Check: Does shutil.move() work on directories? (Answer: Yes, it moves entire directories)
Error Handling When Moving
Robust File Moving
import shutil
import os
# 1. Comprehensive move function
def safe_move(source, destination):
"""Safely move a file or directory with error handling"""
try:
# Check if source exists
if not os.path.exists(source):
print(f"Error: Source '{source}' does not exist")
return False
# Check if destination exists
if os.path.exists(destination):
print(f"Warning: Destination '{destination}' already exists")
response = input("Overwrite? (y/n): ")
if response.lower() != 'y':
print("Move cancelled")
return False
# Perform the move
shutil.move(source, destination)
print(f"Moved: {source} → {destination}")
return True
except PermissionError:
print(f"Error: Permission denied when moving '{source}'")
return False
except OSError as e:
print(f"Error: {e}")
return False
except Exception as e:
print(f"Unexpected error: {e}")
return False
# 2. Move with automatic backup
def move_with_backup(source, destination):
"""Move with automatic backup of existing destination"""
if os.path.exists(destination):
backup = destination + ".backup"
shutil.move(destination, backup)
print(f"Existing destination backed up as: {backup}")
return safe_move(source, destination)
# 3. Move with verification
def move_and_verify(source, destination):
"""Move and verify the operation was successful"""
if safe_move(source, destination):
if not os.path.exists(source) and os.path.exists(destination):
print("Move verified successfully")
return True
else:
print("Move verification failed")
return False
return False
Common move errors:
- FileNotFoundError — source doesn't exist
- PermissionError — can't access source or destination
- OSError — other operating system issues
- Always handle errors — make your code robust
Quick Check: What error occurs when you try to move a file that doesn't exist? (Answer: FileNotFoundError)
Best Practices for Moving Files
Professional File Moving Guidelines
import shutil
import os
# 1. Always check if source exists
def smart_move(source, destination):
"""Move with existence checks"""
if not os.path.exists(source):
print(f"Cannot move: '{source}' does not exist")
return False
try:
shutil.move(source, destination)
print(f"Moved: {source} → {destination}")
return True
except Exception as e:
print(f"Error: {e}")
return False
# 2. Create destination directory if needed
def move_with_dirs(source, destination):
"""Move and create destination directory if needed"""
dest_dir = os.path.dirname(destination)
if dest_dir and not os.path.exists(dest_dir):
os.makedirs(dest_dir, exist_ok=True)
print(f"Created directory: {dest_dir}")
return smart_move(source, destination)
# 3. Use the right tool for the job
# For moving between directories: shutil.move()
# For simple renaming: os.rename()
# For copying: shutil.copy()
# 4. Handle conflicts gracefully
def move_with_conflict_handling(source, destination):
"""Move with conflict resolution options"""
if os.path.exists(destination):
print(f"Destination '{destination}' exists")
print("Options:")
print(" [o] Overwrite")
print(" [b] Backup existing")
print(" [s] Skip this file")
print(" [c] Cancel all")
choice = input("Choose option: ").lower()
if choice == 'o':
return smart_move(source, destination)
elif choice == 'b':
backup = destination + ".backup"
shutil.move(destination, backup)
print(f"Backed up: {destination} → {backup}")
return smart_move(source, destination)
elif choice == 's':
print(f"Skipped: {source}")
return False
else:
print("Cancelled")
return False
return smart_move(source, destination)
# 5. Use meaningful destination names
# ✅ Good
# archive/report_2026_08.csv
# processed/data_final.txt
# ❌ Bad
# temp/file.txt
# new/file.txt
Best practices summary:
- Check source — verify file/directory exists
- Create directories — ensure destination exists
- Handle conflicts — deal with existing files
- Use right tool — move vs rename vs copy
- Meaningful names — use clear naming conventions
Quick Check: What is the most important check before moving a file? (Answer: Verify the source exists)
Try It Yourself
Experiment with moving files in the editor below. Try different move operations and see the results.
MOVE FILE PRACTICE
========================================
1. CREATING SAMPLE FILES
Created: original.txt
2. BASIC MOVE
Moved: original.txt → moved.txt
3. MOVE TO DIRECTORY
Moved: moved.txt → archive/
4. MOVE AND RENAME
Moved and renamed: archive/moved.txt → archive/final.txt
5. CHECKING RESULTS
Files in archive directory: ['final.txt']
original.txt is gone (as expected)
Move file practice complete!
You've Got It!
You now know how to move files and directories in Python. You understand the difference between moving and renaming, and how to handle errors professionally.
Quick Quiz
Test what you've learned:
Frequently Asked Questions
What is the difference between moving and copying a file?
Can I use shutil.move() to rename a file?
What happens if the destination already exists?
What's a common interview question about moving files?
Can I move files between different drives or filesystems?
How do I move a file safely without losing data?
Where to Go From Here
Now that you can move files, check out these related topics:
List Files in Directory
Learn how to list and filter files.
Learn More →Binary Files
Learn how to read and write binary files.
Learn More →Zipping and Unzipping Files
Learn how to compress and extract files.
Learn More →