Created
November 10, 2025 05:15
-
-
Save rhaseven7h/cfd4303e8b9ee27c9f5f2937112eadfb to your computer and use it in GitHub Desktop.
Quick python script to rename files in a diretory, has allow/deny functionality and renaming based on regular expressions
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 python | |
| import os | |
| import re | |
| import sys | |
| def generate_new_name(filename): | |
| """ | |
| Generates a new name for a file by removing a pattern matching the regular | |
| expression ' \[A-Za-z0-9\]+ - handbroken.*', cleaning up symbols, | |
| and keeping the original extension. | |
| """ | |
| name, ext = os.path.splitext(filename) | |
| # Remove the main pattern | |
| new_name = re.sub(r" \[[A-Za-z0-9]+\] - handbroken.*", "", name) | |
| # Replace underscores and dashes with a space | |
| new_name = new_name.replace('_', ' ').replace('-', ' ') | |
| # Remove any character that is not a letter, number, space, or apostrophe | |
| new_name = re.sub(r"[^a-zA-Z0-9\s']", '', new_name) | |
| # Replace multiple spaces with a single space and trim whitespace | |
| new_name = re.sub(r'\s+', ' ', new_name).strip() | |
| # Capitalize the new name | |
| new_name = new_name.capitalize() | |
| return new_name + ext | |
| def rename_files(): | |
| """ | |
| Traverses all files in the current directory and renames them based on | |
| a configurable allow/deny filter system. | |
| """ | |
| # --- Configuration --- | |
| # Set the filtering order: "allow-then-deny" or "deny-then-allow" | |
| filter_order = "allow-then-deny" | |
| # Files matching these patterns will be considered for processing. | |
| # If filter_order is "allow-then-deny" and this list is empty, all files are initially allowed. | |
| allow_patterns = [r".*"] | |
| # Files matching these patterns will be excluded from processing. | |
| deny_patterns = [ | |
| r".*\.py", # Deny all Python files | |
| r"\.DS_Store", # Deny macOS metadata files | |
| ] | |
| # --- End Configuration --- | |
| # --- Validate Configuration --- | |
| if filter_order not in ["allow-then-deny", "deny-then-allow"]: | |
| raise ValueError(f"Invalid filter_order: '{filter_order}'. Must be 'allow-then-deny' or 'deny-then-allow'.") | |
| # --- End Validation --- | |
| for filename in os.listdir('.'): | |
| if not os.path.isfile(filename): | |
| continue | |
| # --- Filtering Logic --- | |
| is_allowed = any(re.fullmatch(p, filename) for p in allow_patterns) | |
| is_denied = any(re.fullmatch(p, filename) for p in deny_patterns) | |
| should_process = False | |
| if filter_order == "allow-then-deny": | |
| # Process if it's in the allow list (or if the list is empty) AND it's not in the deny list. | |
| should_process = (not allow_patterns or is_allowed) and not is_denied | |
| elif filter_order == "deny-then-allow": | |
| # Process if it's NOT in the deny list, OR if it's explicitly in the allow list (as an exception). | |
| should_process = not is_denied or is_allowed | |
| if not should_process: | |
| continue | |
| # --- End Filtering Logic --- | |
| new_name = generate_new_name(filename) | |
| if new_name != filename: | |
| print(f"Renaming:\n\t'{filename}'\n\t'{new_name}'") | |
| if "-x" in sys.argv: | |
| os.rename(filename, new_name) | |
| if __name__ == "__main__": | |
| args = sys.argv[1:] | |
| is_dry_run = not (len(args) == 1 and args[0] == '-x') | |
| if not (len(args) == 0 or is_dry_run is False): | |
| print("Error: Invalid arguments. Use no arguments for a dry run, or '-x' to execute renaming.", file=sys.stderr) | |
| sys.exit(1) | |
| if is_dry_run: | |
| print("--- DRY RUN: NO FILES WILL BE RENAMED ---") | |
| rename_files() | |
| if is_dry_run: | |
| print("--- END OF DRY RUN ---") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment