求助:将Python文件夹拆分器修改为文件拆分器的方法
修改文件夹拆分脚本为文件分组脚本
原脚本功能与代码
原脚本用于将当前目录下的大量文件夹按最多255个每组,拆分到新的分类文件夹中,原代码如下:
#gadgetmiser's idempotent splitter import os from shutil import move wd = os.getcwd() dirs = os.listdir(wd) lastitemindex = len(dirs) - 1 drive = wd.split(':')[0] results = ':\\c64Romset_output\\' filesperfolder = 255 letterstodisplay = 15 firstfn_2l = dirs[0][:letterstodisplay].split("(")[0].strip().upper()[:4] lastfn_2l = dirs[:filesperfolder - 1][-1][:letterstodisplay].split("(")[0].strip().upper()[:4] firsttarget = (firstfn_2l + " to " + lastfn_2l).strip() os.mkdir(drive + results) os.mkdir(drive + results + firsttarget) log_output = open(drive + results + "log_output.txt","w+") tally = 0 counter = 0 target = firsttarget for folder in dirs: tally += 1 if counter == filesperfolder: p1 = folder[:letterstodisplay].split("(")[0].upper().strip()[:4] folderpos = dirs.index(folder) try: p2 = dirs[folderpos + filesperfolder - 1][:letterstodisplay].split("(")[0].upper().strip()[:4] except IndexError: p2 = dirs[lastitemindex][:letterstodisplay].split("(")[0].upper().strip()[:4] newdir = (p1 + " to " + p2).strip() print(str(tally) + " files processed ... making new dir called: " + newdir) target = newdir counter = 0 newfname = folder.split("(")[0].strip() move(folder, drive + results + target + "\\" + newfname) print("Moved " + folder + " to " + drive + results + target + " as " + newfname) log_output.write("\n" + "Moved " + folder + " to: ** " + target + " **" + " as " + newfname) counter += 1 print(str(tally) + ' files processed ... ALL DONE') log_output.write("\n" + str(tally) + " files processed.") log_output.close()
用户需求与问题
需要将脚本修改为处理文件:把当前目录下的大量文件(如10000个)按最多255个每组拆分到对应新文件夹,例如1000个文件拆分为4个文件夹(255、255、255、235个文件/文件夹)。
尝试直接将代码中所有folder替换为files后无报错,但未生成目标文件夹,需要具体修改方法。
修改方案与最终代码
直接替换变量名无效的原因:原脚本默认处理所有目录条目(包括文件夹),且逻辑是移动文件夹而非文件,还存在目录创建、文件名处理等适配问题。以下是针对性修改后的代码:
# 修改版:按最多255个每组拆分文件到新文件夹 import os from shutil import move wd = os.getcwd() # 过滤出当前目录下的所有文件,排除文件夹 files = [f for f in os.listdir(wd) if os.path.isfile(os.path.join(wd, f))] if not files: print("当前目录下无文件可处理") exit() lastitemindex = len(files) - 1 drive = wd.split(':')[0] results = ':\\c64Romset_output\\' filesperfolder = 255 letterstodisplay = 15 # 创建根输出目录(如果已存在则不报错) os.makedirs(drive + results, exist_ok=True) # 生成第一个目标文件夹名称 first_file_prefix = files[0][:letterstodisplay].split("(")[0].strip().upper()[:4] # 取第一组最后一个文件的前缀(避免文件数量不足时索引越界) last_file_idx = min(filesperfolder - 1, lastitemindex) last_file_prefix = files[last_file_idx][:letterstodisplay].split("(")[0].strip().upper()[:4] firsttarget = f"{first_file_prefix} to {last_file_prefix}".strip() # 创建第一个目标文件夹 os.makedirs(os.path.join(drive, results, firsttarget), exist_ok=True) log_path = os.path.join(drive, results, "log_output.txt") log_output = open(log_path, "w+") tally = 0 counter = 0 target = firsttarget # 使用enumerate遍历,直接获取索引,避免低效的index查找 for idx, file in enumerate(files): tally += 1 # 当计数器达到每组上限时,创建新的目标文件夹 if counter == filesperfolder: # 取当前文件的前缀作为新文件夹的起始标识 p1 = file[:letterstodisplay].split("(")[0].upper().strip()[:4] # 计算该组最后一个文件的索引 end_idx = idx + filesperfolder - 1 # 如果超出总文件数,取最后一个文件的前缀 if end_idx > lastitemindex: p2 = files[lastitemindex][:letterstodisplay].split("(")[0].upper().strip()[:4] else: p2 = files[end_idx][:letterstodisplay].split("(")[0].upper().strip()[:4] newdir = f"{p1} to {p2}".strip() print(f"{tally} files processed ... making new dir called: {newdir}") target = newdir # 创建新文件夹(已存在则不报错) os.makedirs(os.path.join(drive, results, target), exist_ok=True) counter = 0 # 保留原文件名(包括扩展名),不修改文件名 target_path = os.path.join(drive, results, target, file) move(os.path.join(wd, file), target_path) print(f"Moved {file} to {target_path}") log_output.write(f"\nMoved {file} to: ** {target} **") counter += 1 print(f"{tally} files processed ... ALL DONE") log_output.write(f"\n{tally} files processed.") log_output.close()
关键修改点说明
- 过滤文件:用列表推导式筛选出当前目录下的文件,排除文件夹,避免误处理目录。
- 安全创建目录:使用
os.makedirs(exist_ok=True)代替os.mkdir,如果输出目录已存在不会报错,适配重复运行场景。 - 修正分组索引:用
min()处理第一组最后一个文件的索引,避免文件总数不足255时出现索引越界;遍历用enumerate直接获取文件索引,比dirs.index()更高效且避免异常。 - 保留原文件名:移除原脚本中修改文件名的逻辑,确保文件移动后保留原扩展名和完整名称,避免文件格式丢失。
- 边界处理:当最后一组文件数量不足255时,自动取最后一个文件的前缀作为文件夹名称的结束标识。
内容的提问来源于stack exchange,提问作者Guybrush16bit
相关产品推荐
相关产品推荐

