import os import shutil import argparse # =============== 全局路径配置 =============== REJECT_ROOT = r"D:\videos" # 包含rejected_files.txt的根路径 DELETE_ROOT = "E:" # 要删除文件夹的根路径 # =============== 结束配置 =============== def find_rejected_files(root_path): """在指定根路径下递归查找所有名为rejected_files.txt的文件""" rejected_files = [] for root, dirs, files in os.walk(root_path): if 'rejected_files.txt' in files: rejected_files.append(os.path.join(root, 'rejected_files.txt')) return rejected_files def read_folder_names(file_paths): """读取多个TXT文件中的文件夹名称,提取'] '后的字符(严格去空格,确保名称完全匹配)""" folder_names = [] unique_names = set() # 用于去重 for file_path in file_paths: if not os.path.exists(file_path): print(f"警告:文件 {file_path} 不存在,已跳过") continue with open(file_path, 'r', encoding='utf-8') as f: for line_num, line in enumerate(f, 1): raw_line = line.strip() if not raw_line or raw_line.startswith('#'): continue if "] " in raw_line: folder_name = raw_line.split("] ", 1)[1].strip() else: folder_name = raw_line.strip() if folder_name and folder_name not in unique_names: unique_names.add(folder_name) folder_names.append(folder_name) print(f"从 {os.path.basename(file_path)} 提取有效名称(第{line_num}行):'{folder_name}'") elif not folder_name: print(f"警告:{os.path.basename(file_path)} 第{line_num}行提取后为空,已忽略(原始内容:{raw_line})") return folder_names def find_matching_folders_recursively(root_path, target_names): """在指定根路径下递归查找所有名称与目标列表完全一致的文件夹""" matching_folders = [] for root, dirs, files in os.walk(root_path): for dir_name in dirs: if dir_name in target_names: folder_path = os.path.join(root, dir_name) matching_folders.append(folder_path) return matching_folders def delete_matching_folders(root_path, names_to_delete): """递归删除指定根路径下所有名称与不通过列表完全一致的文件夹""" if not os.path.isdir(root_path): print(f"错误:源路径 {root_path} 不是有效目录,无法删除") return 0 folders_to_delete = find_matching_folders_recursively(root_path, names_to_delete) if not folders_to_delete: print("没有找到匹配的文件夹需要删除") return 0 print("\n找到以下匹配的文件夹:") for i, folder in enumerate(folders_to_delete, 1): print(f"{i}. {folder}") # 询问用户确认删除 while True: user_input = input("\n确定要删除以上所有文件夹吗?(y/n): ").strip().lower() if user_input == 'y': break elif user_input == 'n': print("取消删除操作") return 0 else: print("请输入 'y' 或 'n'") deleted = 0 for folder_path in folders_to_delete: try: shutil.rmtree(folder_path) deleted += 1 print(f"删除成功:{folder_path}") except Exception as e: print(f"删除失败 {folder_path}:{str(e)}") print(f"\n共成功删除 {deleted} 个文件夹(在 {root_path} 下递归查找)") return deleted def main(): parser = argparse.ArgumentParser(description='根据rejected_files.txt删除匹配的文件夹') parser.add_argument('--reject_root', default=REJECT_ROOT, help=f'包含rejected_files.txt的根路径(默认:{REJECT_ROOT})') parser.add_argument('--delete_root', default=DELETE_ROOT, help=f'要删除文件夹的根路径(默认:{DELETE_ROOT})') args = parser.parse_args() print("=" * 60) print("操作说明:") print(f"1. 将在 {args.reject_root} 下递归查找所有 rejected_files.txt 文件") print(f"2. 收集这些文件中的所有条目作为要删除的文件夹名称") print(f"3. 在 {args.delete_root} 下递归查找并删除匹配的文件夹") print("=" * 60) # 查找所有rejected_files.txt文件 rejected_files = find_rejected_files(args.reject_root) if not rejected_files: print(f"\n错误:在 {args.reject_root} 下未找到任何 rejected_files.txt 文件") return print(f"\n找到 {len(rejected_files)} 个 rejected_files.txt 文件:") for file in rejected_files: print(f" - {file}") # 读取所有不通过的文件夹名称 print("\n----- 读取不通过列表 -----") fail_folders = read_folder_names(rejected_files) if not fail_folders: print("\n错误:未从rejected_files.txt文件中提取到任何有效文件夹名称") return print(f"\n共提取到 {len(fail_folders)} 个需要删除的文件夹名称") # 在删除根路径下递归查找并删除匹配的文件夹 print(f"\n----- 在 {args.delete_root} 中执行删除操作 -----") total_deleted = delete_matching_folders(args.delete_root, fail_folders) print(f"\n总共成功删除 {total_deleted} 个文件夹") if __name__ == "__main__": main()