My picture files are considered duplicates if the name contains "-edited" and/or "(n)", where n is a number between 1 and 9. The following does not work for me: Sample file_name1 "IMAG0320-edited(1).jpg" Sample file_name2 "IMAG0320-edited.jpg" Sample file_name3 "IMAG0320-edited.jpg" The following code works to identify "-edited" files: edited_pattern = re.compile(r"(.+)-edited\.jpg$", re.IGNORECASE) I cannot get the following code to work. numbered_pattern = re.compile(r"(.+)$$(\d)$$\.jpg$", re.IGNORECASE) Here is the whole thing: #!/usr/bin/env python import os import re # Hash containers hash1 = {} hash2 = {} hash3 = {} # Regex patterns edited_pattern = re.compile(r"(.+)-edited\.jpg$", re.IGNORECASE) numbered_pattern = re.compile(r"(.+)$$(\d)$$\.jpg$", re.IGNORECASE) base_pattern = re.compile(r"(.+)\.jpg$", re.IGNORECASE) # Step 1: Traverse and populate the hashes def traverse_and_collect(directory): for root, _, files in os.walk(directory): for file in files: file_path = os.path.join(root, file) file_lower = file.lower() #print ("ALL file" + file + ") file_path" + file_path + ")\n") if edited_pattern.match(file_lower): base_name = edited_pattern.match(file_lower).group(1) + ".jpg" hash1[file_path] = os.path.join(root, base_name) print ("EDT file" + file + ") file_path" + file_path + ")\n") elif numbered_pattern.match(file_lower): base_name = numbered_pattern.match(file_lower).group(1) + ".jpg" hash2[file_path] = os.path.join(root, base_name) print ("NBR file" + file + ") file_path" + file_path + ")\n") elif base_pattern.match(file_lower): if not "-edited.jpg" in file_lower and not numbered_pattern.match(file_lower): hash3[file_path] = file_path print ("CLN file" + file + ") file_path" + file_path + ")\n") # Step 2: Replace keys in hash1 based on matches in hash2 or hash3 def update_hash1_keys(): value_to_alt_key = {} # Build reverse lookup from hash2 and hash3 for k, v in hash2.items(): value_to_alt_key[v] = k for k, v in hash3.items(): value_to_alt_key[v] = k # hash3 takes priority if same value appears in both # Replace keys in hash1 if value found in either hash2 or hash3 new_hash1 = {} for k, v in hash1.items(): if v in value_to_alt_key: new_key = value_to_alt_key[v] new_hash1[new_key] = v else: new_hash1[k] = v return new_hash1 # Main logic if __name__ == "__main__": #directory = input("Enter directory to scan: ").strip() directory = "/mnt/sdb1/google_photos/" traverse_and_collect(directory) print("\n--- Initial Hash1 ---") for k, v in hash1.items(): print(f"{k} -> {v}") hash1_updated = update_hash1_keys() print("\n--- Updated Hash1 (after replacement) ---") for k, v in hash1_updated.items(): print(f"{k} -> {v}") Continue reading...