import os from pathlib import Path def rename_files_in_folders(root_dir: str = ".", recursive: bool = True, dry_run: bool = False): """ Rename files by appending the top-level folder name. Example: image.jpg inside 'extracted_MyBackup' becomes image_MyBackup.jpg """ base_path = Path(root_dir).resolve() if not base_path.exists(): print(f"Error: Folder '{base_path}' does not exist.") return print(f"Scanning folder: {base_path}") if dry_run: print("*** DRY RUN MODE - No files will be renamed ***\n") renamed_count = 0 skipped_count = 0 # Walk through all directories for dir_path in base_path.rglob("*") if recursive else base_path.iterdir(): if not dir_path.is_dir(): continue folder_name = dir_path.name # Skip root folder itself and hidden folders if folder_name.startswith('.') or folder_name == base_path.name: continue print(f"\nProcessing folder: {folder_name}") for file_path in dir_path.iterdir(): if not file_path.is_file(): continue # Get file components original_name = file_path.stem # filename without extension ext = file_path.suffix # .jpg, .png, etc. # Skip if file already has the folder name (to avoid double renaming) if folder_name in original_name: print(f" Skipped (already processed): {file_path.name}") skipped_count += 1 continue # New filename: originalName_folderName.ext new_name = f"{original_name}_{folder_name}{ext}" new_path = file_path.parent / new_name # Check if target file already exists if new_path.exists(): print(f" Warning: Target already exists → {new_name}") skipped_count += 1 continue try: if dry_run: print(f" Would rename: {file_path.name} → {new_name}") else: file_path.rename(new_path) print(f" Renamed: {file_path.name} → {new_name}") renamed_count += 1 except Exception as e: print(f" Error renaming {file_path.name}: {e}") skipped_count += 1 print("\n" + "="*60) print("Renaming completed!") print(f"Files renamed: {renamed_count}") print(f"Files skipped: {skipped_count}") if dry_run: print("This was a DRY RUN — no actual changes were made.") print("="*60) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser( description="Rename files by appending their top-level folder name." ) parser.add_argument("folder", nargs="?", default=".", help="Root folder to process (default: current directory)") parser.add_argument("-r", "--recursive", action="store_true", help="Process subfolders recursively (recommended)") parser.add_argument("--dry-run", action="store_true", help="Show what would be renamed without making changes") args = parser.parse_args() # By default we enable recursive since you usually want to process extracted_ folders rename_files_in_folders( root_dir=args.folder, recursive=args.recursive if hasattr(args, 'recursive') else True, dry_run=args.dry_run )