Python实现的文件夹整理工具
打开下载文件夹或其他文件夹时,你可能会发现无数不同类型的文件(图片、文档、安装程序等)混在一起,不得不花费大量时间寻找ChatGPT生成的作业PDF,想着"真麻烦",或者不得不手动整理20个PDF、10张图片和5个安装程序。我也经历过这种情况,因此决定创建一个脚本,让我可以继续偷懒,同时让文件保持完美有序。
这个使用Python的脚本可以为我完成这项工作。你可以直接在GitHub上查看它。
脚本工作原理
为了构建这个工具,我使用了几个Python库,一些是内置的(“标准库”),还有一个外部库用于在脚本执行时通知我。
步骤1:导入库
1
2
3
4
|
import os
import shutil
import sys
from win10toast import ToastNotifier
|
os(操作系统):允许我们检查文件或文件夹是否存在(os.path.exists),创建文件夹(os.makedirs),列出所有文件(os.listdir)并获取文件扩展名(os.path.splitext)。
shutil(Shell工具):允许我们将文件从一个地方移动到另一个地方(shutil.move())。
sys(系统):sys.executable让我知道脚本在哪里执行,这在编译为.exe文件时非常有用。
ToastNotifier(来自win10toast):这是外部库。它允许我们向Windows发送原生通知。使用pip install wintoast安装。
步骤2:文件映射
创建一个字典作为映射,其中每个键是我们想要创建的文件夹名称(例如"imagenes"),值是该文件夹中应包含的所有文件扩展名的列表。
1
2
3
4
5
6
7
8
9
10
|
notificar = ToastNotifier() # 初始化通知器
tipos_de_archivo = {
"imagenes": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg"],
"videos": [".mp4", ".avi", ".mov", ".mkv", ".webm"],
"documentos": [".pdf", ".doc", ".docx", ".txt", ".xls", ".xlsx"],
"ejecutables y sistema": [".exe", ".msi", ".bat", ".dll"],
"comprimidos": [".zip", ".rar", ".7z", ".iso"],
# ...其他类别也是如此...
"Otros": [] # 特殊类别,用于不匹配的文件
}
|
步骤3:灵活配置(读取rutas.txt)
我不想每次想要添加新文件夹进行整理时都编辑脚本。因此,我让脚本读取一个配置文件rutas.txt。
此函数打开该文件,读取每一行,如果写入的路径确实存在,则将其添加到列表中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def obtener_rutas(ruta_actual, archivo='rutas.txt'):
"""
获取写在config/rutas.txt文件中的路径
"""
rutas_validas = []
# 在'config'文件夹中查找.txt文件
archivo_rutas = os.path.join(ruta_actual, 'config', archivo)
with open(archivo_rutas, 'r', encoding='utf-8') as rutas:
for linea in rutas:
ruta = linea.strip() # .strip()去除空白字符
# 如果路径不为空且存在...
if ruta and os.path.exists(ruta):
rutas_validas.append(os.path.abspath(ruta))
return rutas_validas
|
步骤4:处理重复文件
这是最重要的部分。如果我将tarea.pdf移动到"Documentos",但该文件夹中已存在tarea.pdf怎么办?
为此,有mover_archivo函数。
- 尝试移动它:如果目标位置不存在该文件,则直接移动它(
shutil.move)。
- 如果已存在:
- 创建一个名为"DUPLICADOS"的文件夹。
- 为新文件重命名(例如从
tarea.pdf改为tarea (1).pdf)。
- 查找可用的名称(如果
tarea (1).pdf存在,则尝试tarea (2).pdf,依此类推)。
- 将重命名的文件移动到"DUPLICADOS"文件夹。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
def mover_archivo(origen, destino):
try:
if not os.path.exists(destino):
# 路径可用,正常移动
shutil.move(origen, destino)
else:
# 冲突!文件已存在
carpeta_duplicados = os.path.join(os.path.dirname(destino), "DUPLICADOS")
os.makedirs(carpeta_duplicados, exist_ok=True)
# 查找新名称的逻辑(例如"archivo (1).ext")
contador = 1
base, ext = os.path.splitext(os.path.basename(origen))
nuevo_nombre = f"{base} ({contador}){ext}"
nuevo_destino = os.path.join(carpeta_duplicados, nuevo_nombre)
while os.path.exists(nuevo_destino):
contador += 1
nuevo_nombre = f"{base} ({contador}){ext}"
nuevo_destino = os.path.join(carpeta_duplicados, nuevo_nombre)
shutil.move(origen, nuevo_destino)
except Exception:
# 如果出现任何错误(例如文件正在使用),直接忽略
# 这样脚本不会停止。
pass
|
步骤5:整理功能
此函数遍历我们传递给它的文件夹:
- 使用
os.listdir(ruta)列出所有内容。
- 如果是文件,在我们的"映射"(
tipos_de_archivo)中查找其扩展名,并将其发送到mover_archivo函数。如果未找到扩展名,则将其发送到"Otros"。
- 如果是文件夹(并且不是我们的类别文件夹之一,如"Imagenes"),则将其整个移动到名为"Carpetas"的文件夹中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
def organizar_carpeta(ruta, tipos):
for archivo in os.listdir(ruta):
archivo_path = os.path.join(ruta, archivo)
if os.path.isfile(archivo_path):
# 是文件,查找扩展名
extension = os.path.splitext(archivo_path)[1]
for categoria, extensiones in tipos.items():
if extension.lower() in extensiones:
destino = os.path.join(ruta, categoria, archivo)
break # 找到类别,跳出循环
else:
# 未找到,转到"Otros"
destino = os.path.join(ruta, "Otros", archivo)
mover_archivo(archivo_path, destino)
elif os.path.isdir(archivo_path) and not archivo in tipos.keys():
# 是文件夹,移动到"Carpetas"
destino = os.path.join(ruta, "Carpetas", archivo)
mover_archivo(archivo_path, destino)
|
步骤6:启动运行
if __name__ == "__main__":块是实际执行所有操作的部分。
- 首先,从我们的
rutas.txt获取所有要整理的路径。
- 然后,对每个路径进行
for循环,并调用organizar_carpeta。
- 完成后,使用
notificar.show_toast()发送通知,告诉我执行已完成。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
if __name__ == "__main__":
# ...(查找ruta_script和ruta_icon的代码)...
# 1. 从.txt获取路径
rutas = obtener_rutas(ruta_script)
# 2. 整理每一个路径
for rt in rutas:
organizar_carpeta(rt, tipos_de_archivo)
# 3. 通知
notificar.show_toast(
"文件整理器",
"✅ 下载文件夹中的文件已整理完成!",
icon_path= ruta_icon,
duration=10,
)
|
注意:我使用Windows,因此wintoast适用于通知。如果你使用Linux,可以尝试使用其他库或工具,或者直接跳过此步骤和wintoast的导入。
使用方法
- 访问我的GitHub仓库fiedri’s Toolbox。
- 确保已安装Python和必要的库:
pip install wintoast
- 在脚本旁边创建一个
config文件夹,并在其中创建一个rutas.txt文件。
- 在
rutas.txt中,写入要整理的文件夹的完整路径(例如C:\Users\fiedri\Downloads),每行一个。
- 运行脚本。
如何自动化脚本(Windows)
为了让脚本自动运行,无需任何操作。最简单的方法是使用任务计划程序(Task Scheduler)。
- 在Windows开始菜单中搜索"任务计划程序"。
- 在右侧面板中,点击"创建基本任务…"。
- 给它起个名字,并选择希望它何时运行。我将其配置为在我知道电脑会开机的特定时间每周运行。
- 选择"启动程序"。
- 配置:
- 在"程序/脚本"中,查找并选择你的
python.exe(通常位于C:\Python310\python.exe)。
- 在"添加参数"中,粘贴脚本的完整路径:
C:\ruta\a\tu\organizer_downloads_auto.py。
- 可选:如果将脚本编译为.exe文件(我做了),只需在"程序/脚本"中放入该.exe的路径即可。