python-script-library/递归删除文件夹.py

146 lines
5.5 KiB
Python
Raw Normal View History

2025-10-28 16:02:55 +08:00
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()