Created
August 6, 2025 01:47
-
-
Save kylemcdonald/43724f3054ab1912fb7bd334c1e48525 to your computer and use it in GitHub Desktop.
Python script for copying many files of interest from old hard drives.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import os | |
| import shutil | |
| import argparse | |
| from pathlib import Path | |
| def copy_source_files(source_dir, dest_dir, extensions=('.h', '.cpp', '.pde')): | |
| """ | |
| Recursively find files with specified extensions and copy them to destination | |
| while preserving folder hierarchy. | |
| Args: | |
| source_dir (str): Source directory to search | |
| dest_dir (str): Destination directory to copy files to | |
| extensions (tuple): File extensions to search for | |
| """ | |
| source_path = Path(source_dir) | |
| dest_path = Path(dest_dir) | |
| # Create destination directory if it doesn't exist | |
| dest_path.mkdir(parents=True, exist_ok=True) | |
| copied_count = 0 | |
| # Walk through source directory recursively | |
| for root, dirs, files in os.walk(source_path): | |
| # Filter out build artifacts and non-source directories | |
| excluded_dirs = { | |
| '.xcodeproj', 'libs', 'applet', 'web-export' | |
| } | |
| excluded_patterns = [ | |
| lambda d: d.endswith('.app'), | |
| lambda d: d.endswith('.macosx'), | |
| lambda d: d.startswith('application.') | |
| ] | |
| dirs[:] = [ | |
| d for d in dirs | |
| if d not in excluded_dirs | |
| and not any(pattern(d) for pattern in excluded_patterns) | |
| ] | |
| root_path = Path(root) | |
| # Get relative path from source directory | |
| relative_path = root_path.relative_to(source_path) | |
| # Check each file in current directory | |
| for file in files: | |
| if file.lower().endswith(extensions): | |
| # Create corresponding directory in destination only when we have a file to copy | |
| dest_subdir = dest_path / relative_path | |
| dest_subdir.mkdir(parents=True, exist_ok=True) | |
| source_file = root_path / file | |
| dest_file = dest_subdir / file | |
| try: | |
| shutil.copy2(source_file, dest_file) | |
| print(f"Copied: {source_file} -> {dest_file}") | |
| copied_count += 1 | |
| except Exception as e: | |
| print(f"Error copying {source_file}: {e}") | |
| print(f"\nTotal files copied: {copied_count}") | |
| def main(): | |
| parser = argparse.ArgumentParser( | |
| description="Copy source files (.h, .cpp, .pde) to a new directory while preserving folder structure" | |
| ) | |
| parser.add_argument( | |
| "source_dir", | |
| help="Source directory to search for files" | |
| ) | |
| parser.add_argument( | |
| "dest_dir", | |
| help="Destination directory to copy files to" | |
| ) | |
| parser.add_argument( | |
| "--extensions", | |
| nargs="+", | |
| default=['.h', '.c', '.hpp', '.cpp', '.pde'], | |
| help="File extensions to search for (default: .h .cpp .pde)" | |
| ) | |
| args = parser.parse_args() | |
| # Validate source directory exists | |
| if not os.path.exists(args.source_dir): | |
| print(f"Error: Source directory '{args.source_dir}' does not exist.") | |
| return | |
| # Convert extensions to tuple and ensure they start with dot | |
| extensions = tuple(ext if ext.startswith('.') else f'.{ext}' for ext in args.extensions) | |
| print(f"Searching for files with extensions: {extensions}") | |
| print(f"Source directory: {args.source_dir}") | |
| print(f"Destination directory: {args.dest_dir}") | |
| print("-" * 50) | |
| copy_source_files(args.source_dir, args.dest_dir, extensions) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment