From 11b1e7f3f93a019b8c8773e86349429b4bc5d56a Mon Sep 17 00:00:00 2001 From: SantanDon Date: Sun, 26 Apr 2026 16:25:33 +0200 Subject: [PATCH 1/2] Modernize batch_file_rename with pathlib and add dry-run feature --- batch_file_rename.py | 92 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/batch_file_rename.py b/batch_file_rename.py index b3a4d75e6d5..3ef5a15301b 100644 --- a/batch_file_rename.py +++ b/batch_file_rename.py @@ -1,57 +1,63 @@ -# batch_file_rename.py -# Created: 6th August 2012 - -""" -This will batch rename a group of files in a given directory, -once you pass the current and new extensions -""" - -# just checking -__author__ = "Craig Richards" -__version__ = "1.0" - import argparse import os +from pathlib import Path -def batch_rename(work_dir, old_ext, new_ext): +def batch_rename(work_dir, old_ext, new_ext, dry_run=False): """ This will batch rename a group of files in a given directory, once you pass the current and new extensions """ - # files = os.listdir(work_dir) - for filename in os.listdir(work_dir): - # Get the file extension - split_file = os.path.splitext(filename) - # Unpack tuple element - root_name, file_ext = split_file - # Start of the logic to check the file extensions, if old_ext = file_ext - if old_ext == file_ext: - # Returns changed name of the file with new extention - newfile = root_name + new_ext + work_path = Path(work_dir) + if not work_path.is_dir(): + print(f"Error: {work_dir} is not a valid directory.") + return + + print(f"[*] Scanning {work_dir} for files with extension '{old_ext}'...") + + found_files = list(work_path.glob(f"*{old_ext}")) + if not found_files: + print(f"[!] No files found with extension '{old_ext}'.") + return - # Write the files - os.rename(os.path.join(work_dir, filename), os.path.join(work_dir, newfile)) - print("rename is done!") - print(os.listdir(work_dir)) + for file_path in found_files: + new_file_path = file_path.with_suffix(new_ext) + + if new_file_path.exists(): + print(f"[!] Skip: {new_file_path.name} already exists. Cannot rename {file_path.name}.") + continue + + if dry_run: + print(f"[DRY-RUN] Would rename: {file_path.name} -> {new_file_path.name}") + else: + try: + file_path.rename(new_file_path) + print(f"[+] Renamed: {file_path.name} -> {new_file_path.name}") + except Exception as e: + print(f"[!] Error renaming {file_path.name}: {e}") + + if not dry_run: + print("[*] Batch rename completed.") def get_parser(): parser = argparse.ArgumentParser( - description="change extension of files in a working directory" + description="Change extension of files in a working directory" ) parser.add_argument( "work_dir", - metavar="WORK_DIR", - type=str, - nargs=1, - help="the directory where to change extension", + help="The directory where to change extension", + ) + parser.add_argument( + "old_ext", help="Old extension (e.g., .txt or txt)" ) parser.add_argument( - "old_ext", metavar="OLD_EXT", type=str, nargs=1, help="old extension" + "new_ext", help="New extension (e.g., .md or md)" ) parser.add_argument( - "new_ext", metavar="NEW_EXT", type=str, nargs=1, help="new extension" + "--dry-run", + action="store_true", + help="Preview changes without applying them", ) return parser @@ -60,22 +66,14 @@ def main(): """ This will be called if the script is directly invoked. """ - # adding command line argument parser = get_parser() - args = vars(parser.parse_args()) + args = parser.parse_args() - # Set the variable work_dir with the first argument passed - work_dir = args["work_dir"][0] - # Set the variable old_ext with the second argument passed - old_ext = args["old_ext"][0] - if old_ext and old_ext[0] != ".": - old_ext = "." + old_ext - # Set the variable new_ext with the third argument passed - new_ext = args["new_ext"][0] - if new_ext and new_ext[0] != ".": - new_ext = "." + new_ext + work_dir = args.work_dir + old_ext = args.old_ext if args.old_ext.startswith(".") else "." + args.old_ext + new_ext = args.new_ext if args.new_ext.startswith(".") else "." + args.new_ext - batch_rename(work_dir, old_ext, new_ext) + batch_rename(work_dir, old_ext, new_ext, dry_run=args.dry_run) if __name__ == "__main__": From af568121da5d03accec0615755930738840bba65 Mon Sep 17 00:00:00 2001 From: SantanDon Date: Sun, 26 Apr 2026 21:38:41 +0200 Subject: [PATCH 2/2] Address CodeRabbit review: narrow exception types, route errors to stderr, and support compound extensions --- batch_file_rename.py | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/batch_file_rename.py b/batch_file_rename.py index 3ef5a15301b..05fa7391916 100644 --- a/batch_file_rename.py +++ b/batch_file_rename.py @@ -1,18 +1,29 @@ import argparse -import os +import sys from pathlib import Path def batch_rename(work_dir, old_ext, new_ext, dry_run=False): """ - This will batch rename a group of files in a given directory, - once you pass the current and new extensions + Batch rename files in a directory from one extension to another. + + Args: + work_dir (str): Path to the target directory. + old_ext (str): Extension to find (e.g., '.txt' or '.tar.gz'). + new_ext (str): New extension to apply (e.g., '.md'). + dry_run (bool): If True, preview changes without applying. """ work_path = Path(work_dir) if not work_path.is_dir(): - print(f"Error: {work_dir} is not a valid directory.") + print(f"Error: {work_dir} is not a valid directory.", file=sys.stderr) return + # Normalize extensions for library safety + if not old_ext.startswith("."): + old_ext = "." + old_ext + if not new_ext.startswith("."): + new_ext = "." + new_ext + print(f"[*] Scanning {work_dir} for files with extension '{old_ext}'...") found_files = list(work_path.glob(f"*{old_ext}")) @@ -21,10 +32,15 @@ def batch_rename(work_dir, old_ext, new_ext, dry_run=False): return for file_path in found_files: - new_file_path = file_path.with_suffix(new_ext) + # Handle compound extensions by checking ends-with + if file_path.name.endswith(old_ext): + new_name = file_path.name[:-len(old_ext)] + new_ext + new_file_path = file_path.with_name(new_name) + else: + new_file_path = file_path.with_suffix(new_ext) if new_file_path.exists(): - print(f"[!] Skip: {new_file_path.name} already exists. Cannot rename {file_path.name}.") + print(f"[!] Skip: {new_file_path.name} already exists. Cannot rename {file_path.name}.", file=sys.stderr) continue if dry_run: @@ -33,14 +49,18 @@ def batch_rename(work_dir, old_ext, new_ext, dry_run=False): try: file_path.rename(new_file_path) print(f"[+] Renamed: {file_path.name} -> {new_file_path.name}") - except Exception as e: - print(f"[!] Error renaming {file_path.name}: {e}") + except OSError as e: + print(f"[!] Error renaming {file_path.name}: {e}", file=sys.stderr) + continue if not dry_run: print("[*] Batch rename completed.") def get_parser(): + """ + Create and return the argument parser for the CLI. + """ parser = argparse.ArgumentParser( description="Change extension of files in a working directory" )