Skip to content

Instantly share code, notes, and snippets.

@yanli0303
Created August 15, 2025 12:16
Show Gist options
  • Select an option

  • Save yanli0303/95f3d81ed0da0d1255e18ca5348ddfb5 to your computer and use it in GitHub Desktop.

Select an option

Save yanli0303/95f3d81ed0da0d1255e18ca5348ddfb5 to your computer and use it in GitHub Desktop.
Rename subdirectories by regular expression
#!/usr/bin/env python3
"""
Script to rename directories by removing trailing " (\\d\\dP)" pattern.
Usage:
python rename_directories.py /path/to/directory
Example:
python rename_directories.py ~/Desktop/videos
"""
import argparse
import re
import sys
from pathlib import Path
def rename_directories(base_path):
"""
Rename all subdirectories in the given path by removing trailing " \\(\\+P(.*)\\)" pattern.
Args:
base_path (str): Path to the directory containing subdirectories to rename
"""
base_path = Path(base_path)
if not base_path.exists():
print(f"Error: Directory '{base_path}' does not exist.")
return False
if not base_path.is_dir():
print(f"Error: '{base_path}' is not a directory.")
return False
# Pattern to match "\s\(\d+P.*\)$" at the end of directory names
pattern = re.compile(r"\s\(\d+P.*\)$")
renamed_count = 0
error_count = 0
# Get all subdirectories
subdirs = [d for d in base_path.iterdir() if d.is_dir()]
if not subdirs:
print(f"No subdirectories found in '{base_path}'.")
return True
print(f"Found {len(subdirs)} subdirectories to process...")
for subdir in subdirs:
dir_name = subdir.name
# Check if the directory name matches the pattern
if pattern.search(dir_name):
new_name = pattern.sub("", dir_name)
new_path = subdir.parent / new_name
# Check if a directory with the new name already exists
if new_path.exists():
print(f"Warning: '{new_name}' already exists. Skipping '{dir_name}'.")
error_count += 1
continue
try:
print(f"Renaming: '{dir_name}' -> '{new_name}'")
subdir.rename(new_path)
renamed_count += 1
except OSError as e:
print(f"Error renaming '{dir_name}': {e}")
error_count += 1
else:
print(f"No pattern match: '{dir_name}' (skipped)")
print("\nSummary:")
print(f" Directories renamed: {renamed_count}")
print(f" Errors encountered: {error_count}")
print(f" Total processed: {len(subdirs)}")
return error_count == 0
def main():
parser = argparse.ArgumentParser(
description="Remove trailing ' (\\d\\dP)' pattern from directory names",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python rename_directories.py ~/Downloads/movies
This script will rename directories like:
"Movie Name (1080P)" -> "Movie Name"
"Video Title (720P)" -> "Video Title"
""",
)
parser.add_argument("directory", help="Path to the directory containing subdirectories to rename")
parser.add_argument("--dry-run", action="store_true", help="Show what would be renamed without actually renaming")
args = parser.parse_args()
if args.dry_run:
print("DRY RUN MODE - No actual renaming will be performed\n")
dry_run_preview(args.directory)
else:
success = rename_directories(args.directory)
sys.exit(0 if success else 1)
def dry_run_preview(base_path):
"""Show what would be renamed in dry-run mode."""
base_path = Path(base_path)
if not base_path.exists():
print(f"Error: Directory '{base_path}' does not exist.")
return
if not base_path.is_dir():
print(f"Error: '{base_path}' is not a directory.")
return
pattern = re.compile(r" \(\d{2}P\)$")
subdirs = [d for d in base_path.iterdir() if d.is_dir()]
if not subdirs:
print(f"No subdirectories found in '{base_path}'.")
return
rename_candidates = []
for subdir in subdirs:
dir_name = subdir.name
if pattern.search(dir_name):
new_name = pattern.sub("", dir_name)
rename_candidates.append((dir_name, new_name))
else:
print(f"No change needed: '{dir_name}'")
if rename_candidates:
print(f"\nThe following {len(rename_candidates)} directories would be renamed:")
for old_name, new_name in rename_candidates:
print(f" '{old_name}' -> '{new_name}'")
else:
print("No directories match the pattern for renaming.")
if __name__ == "__main__":
main()
@yanli0303
Copy link
Copy Markdown
Author

yanli0303 commented Aug 15, 2025

uv run https://gist.github.com/yanli0303/95f3d81ed0da0d1255e18ca5348ddfb5/raw/ -h 

usage: rename_subdirectories_by_regex.py [-h] [--dry-run] directory

Remove trailing '\s\(\d+P.*\)$' pattern from directory names

positional arguments:
  directory   Path to the directory containing subdirectories to rename

options:
  -h, --help  show this help message and exit
  --dry-run   Show what would be renamed without actually renaming

Examples:
  python3 rename_subdirectories_by_regex.py ~/Downloads/movies

This script will rename directories like:
  "Movie Name (1080P)" -> "Movie Name"
  "Video Title (720P)" -> "Video Title"

@yanli0303
Copy link
Copy Markdown
Author

TODO:

  • Accept Regular Expression as input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment