Python script to fix mv --backup=numbered file extensions
After using mv --backup=numbered
, you’ll end up with a lot of files with names such as
001.jpg.~1~
001.jpg.~2~
001.jpg.~3~
etc.
The following Python script renames those files to
001.1.jpg
001.2.jpg
001.3.jpg
preserving the original file extension.
#!/usr/bin/env python3
import os
import re
import argparse
def rename_backup_files(directory, recursive=False):
# Regular expression to match files like "161.jpg.~2~"
pattern = re.compile(r"^(.*)\.\~(\d+)\~$")
# Get all files in current directory
for item in os.listdir(directory):
item_path = os.path.join(directory, item)
# If recursive is True and item is a directory, process it
if recursive and os.path.isdir(item_path):
rename_backup_files(item_path, recursive)
continue
match = pattern.match(item)
if match:
base_name = match.group(1) # e.g., "161.jpg"
number = int(match.group(2)) # e.g., 2
# Extract base file name and extension
name, ext = os.path.splitext(base_name)
# Create the new filename
new_filename = f"{name}.{number}{ext}"
# Increment the number until the new filename is unique
while os.path.exists(os.path.join(directory, new_filename)):
number += 1
new_filename = f"{name}.{number}{ext}"
# Rename the file
old_path = os.path.join(directory, item)
new_path = os.path.join(directory, new_filename)
os.rename(old_path, new_path)
print(f"Renamed: {os.path.join(directory, item)} -> {os.path.join(directory, new_filename)}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Rename backup files in a directory.")
parser.add_argument("directory", type=str, help="Path to the directory containing the files to rename.")
parser.add_argument("-r", "--recursive", action="store_true",
help="Recursively process subdirectories")
args = parser.parse_args()
rename_backup_files(args.directory, args.recursive)
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow