146 lines
5.5 KiB
Python
146 lines
5.5 KiB
Python
|
|
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()
|