电脑用久了,桌面和下载文件夹里总会堆积大量混乱的文件,比如“新建文件夹 (1)”“最终版2”等。利用 Python 标准库的 os、shutil、hashlib、datetime 等模块,只需几十行代码就能实现批量重命名、按类型归档、删除重复文件(基于文件名+大小或内容哈希)、按日期归档、清空空文件夹等自动整理操作。以下代码均可在 Windows/Linux/macOS 下运行,建议先开启 dry_run 预览再实际执行。
一、批量重命名
1. 统一命名规则
函数 batch_rename 接收目录、前缀、起始编号和编号位数,将文件按修改时间排序后依次重命名。
- import os
- def batch_rename(directory, prefix="file", start=1, digits=3):
- files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
- files.sort(key=lambda x: os.path.getmtime(os.path.join(directory, x)))
- for i, filename in enumerate(files):
- name, ext = os.path.splitext(filename)
- new_name = f"{prefix}_{str(start + i).zfill(digits)}{ext}"
- os.rename(os.path.join(directory, filename), os.path.join(directory, new_name))
- print(f"{filename} → {new_name}")
- # 示例:将 D:/照片/2026婚纱照 下文件重命名为 wedding_001.jpg 等
- batch_rename("D:/照片/2026婚纱照", prefix="wedding", start=1, digits=3)
- # 示例:将课件重命名为 note_01.docx 等
- batch_rename("D:/下载/课件", prefix="note", start=1, digits=2)
复制代码
2. 添加日期前缀
使用 datetime.now() 获取当天日期,对未包含该前缀的文件添加“YYYYMMDD_”前缀。
- from datetime import datetime
- def add_date_prefix(directory):
- today = datetime.now().strftime("%Y%m%d")
- for f in os.listdir(directory):
- filepath = os.path.join(directory, f)
- if os.path.isfile(filepath) and not f.startswith(today):
- new_name = f"{today}_{f}"
- os.rename(filepath, os.path.join(directory, new_name))
- print(f"添加前缀: {f} → {new_name}")
- add_date_prefix("D:/下载/课件")
复制代码
3. 批量替换文件名中的文字
替换文件名的任意子串,例如去掉“【课程资料】”或统一空格。
- def replace_filename_text(directory, old_text, new_text):
- count = 0
- for f in os.listdir(directory):
- filepath = os.path.join(directory, f)
- if os.path.isfile(filepath) and old_text in f:
- new_name = f.replace(old_text, new_text)
- os.rename(filepath, os.path.join(directory, new_name))
- print(f"替换: {f} → {new_name}")
- count += 1
- print(f"共替换 {count} 个文件")
- replace_filename_text("D:/课件", "【课程资料】", "")
- replace_filename_text("D:/下载", " ", " ") # 双空格变单空格
复制代码
二、按类型自动归档
定义 EXTENSION_MAP 将文件扩展名映射到目标子文件夹,然后调用 shutil.move 移动文件。同名文件自动添加 _1 后缀。
- import shutil
- EXTENSION_MAP = {
- ".jpg": "图片", ".jpeg": "图片", ".png": "图片",
- ".gif": "图片", ".bmp": "图片", ".webp": "图片",
- ".doc": "文档", ".docx": "文档", ".pdf": "文档",
- ".xls": "表格", ".xlsx": "表格",
- ".ppt": "演示文稿", ".pptx": "演示文稿",
- ".txt": "文本", ".md": "文本",
- ".zip": "压缩包", ".rar": "压缩包", ".7z": "压缩包",
- ".mp4": "视频", ".avi": "视频", ".mov": "视频",
- ".py": "代码", ".java": "代码", ".js": "代码",
- ".html": "代码", ".css": "代码", ".sql": "代码",
- }
- def auto_sort_files(directory):
- if not os.path.exists(directory):
- print(f"文件夹不存在: {directory}")
- return
- moved_count = 0
- for f in os.listdir(directory):
- filepath = os.path.join(directory, f)
- if not os.path.isfile(filepath):
- continue
- _, ext = os.path.splitext(f)
- ext = ext.lower()
- folder_name = EXTENSION_MAP.get(ext, "其他")
- target_dir = os.path.join(directory, folder_name)
- os.makedirs(target_dir, exist_ok=True)
- target_path = os.path.join(target_dir, f)
- if not os.path.exists(target_path):
- shutil.move(filepath, target_path)
- else:
- name, ext = os.path.splitext(f)
- target_path = os.path.join(target_dir, f"{name}_1{ext}")
- shutil.move(filepath, target_path)
- moved_count += 1
- print(f"整理完成!{moved_count} 个文件已归档")
- auto_sort_files("D:/下载")
复制代码
三、删除重复文件
1. 按文件名+大小查找
用 os.walk 遍历所有文件,以 (文件名, 文件大小) 为键存入字典,遇到重复则记录。提供 dry_run 参数预览。
- def find_duplicates(directory):
- files_info = {}
- duplicates = []
- for root, _, files in os.walk(directory):
- for f in files:
- filepath = os.path.join(root, f)
- size = os.path.getsize(filepath)
- key = (f, size)
- if key in files_info:
- duplicates.append((filepath, files_info[key]))
- else:
- files_info[key] = filepath
- return duplicates
- def delete_duplicates(directory, dry_run=True):
- duplicates = find_duplicates(directory)
- if not duplicates:
- print("没有找到重复文件")
- return
- print(f"找到 {len(duplicates)} 组重复文件:\n")
- for dup, original in duplicates:
- print(f" 保留: {original}")
- print(f" 删除: {dup}\n")
- if dry_run:
- print(f"以上是预览结果,共可清理 {len(duplicates)} 个文件")
- print(f"确认删除请运行: delete_duplicates('{directory}', dry_run=False)")
- else:
- for dup, _ in duplicates:
- os.remove(dup)
- print(f"已删除 {len(duplicates)} 个重复文件")
- delete_duplicates("D:/照片", dry_run=True)
复制代码
2. 按内容哈希(MD5)查找更准确
即使文件名不同,只要内容完全一致也能识别。
- import hashlib
- def find_duplicates_by_hash(directory):
- hash_map = {}
- duplicates = []
- for root, _, files in os.walk(directory):
- for f in files:
- filepath = os.path.join(root, f)
- try:
- with open(filepath, "rb") as fh:
- file_hash = hashlib.md5(fh.read()).hexdigest()
- except:
- continue
- if file_hash in hash_map:
- duplicates.append((filepath, hash_map[file_hash]))
- else:
- hash_map[file_hash] = filepath
- return duplicates
复制代码
四、按日期归档
根据文件修改时间,按“年+月”创建子文件夹,将指定扩展名的文件移入。
- def archive_by_month(directory, file_extensions=None):
- if file_extensions is None:
- file_extensions = [".jpg", ".jpeg", ".png", ".gif", ".mp4"]
- moved = 0
- for f in os.listdir(directory):
- filepath = os.path.join(directory, f)
- if not os.path.isfile(filepath):
- continue
- _, ext = os.path.splitext(f)
- if ext.lower() not in file_extensions:
- continue
- mtime = os.path.getmtime(filepath)
- year_month = datetime.fromtimestamp(mtime).strftime("%Y年%m月")
- target_dir = os.path.join(directory, year_month)
- os.makedirs(target_dir, exist_ok=True)
- shutil.move(filepath, os.path.join(target_dir, f))
- moved += 1
- print(f"已归档 {moved} 个文件")
- archive_by_month("D:/照片")
复制代码
五、清空空文件夹
递归遍历目录,从最底层删除空文件夹。
- def remove_empty_dirs(directory):
- removed = 0
- for root, dirs, files in os.walk(directory, topdown=False):
- for d in dirs:
- dirpath = os.path.join(root, d)
- try:
- if not os.listdir(dirpath):
- os.rmdir(dirpath)
- print(f"删除空文件夹: {dirpath}")
- removed += 1
- except:
- pass
- print(f"共删除 {removed} 个空文件夹")
复制代码
六、一键整理桌面
组合上述功能,先按类型归档,再删空文件夹,最后查找重复文件。
- def clean_desktop():
- desktop = os.path.expanduser("~/Desktop")
- print(f"整理桌面: {desktop}")
- auto_sort_files(desktop)
- remove_empty_dirs(desktop)
- duplicates = find_duplicates(desktop)
- if duplicates:
- print(f"桌面有 {len(duplicates)} 组重复文件")
- for d, o in duplicates[:5]:
- print(f" {os.path.basename(d)}")
- else:
- print("无重复文件")
- print("桌面整理完成!")
- # 谨慎使用:会移动桌面上所有文件
- # clean_desktop()
复制代码
七、文件整理工具箱类
将常用操作封装为 FileOrganizer 类,支持预览文件统计和一键整理。
- class FileOrganizer:
- def __init__(self, base_dir):
- self.base_dir = base_dir
- def preview(self):
- total = 0
- ext_count = {}
- for f in os.listdir(self.base_dir):
- fp = os.path.join(self.base_dir, f)
- if os.path.isfile(fp):
- total += 1
- _, ext = os.path.splitext(f)
- ext_count[ext] = ext_count.get(ext, 0) + 1
- print(f"📁 {self.base_dir}")
- print(f"📄 共 {total} 个文件")
- for ext, cnt in sorted(ext_count.items(), key=lambda x: -x[1])[:10]:
- print(f" {ext}: {cnt}个")
- def organize(self):
- print("开始整理...")
- auto_sort_files(self.base_dir)
- remove_empty_dirs(self.base_dir)
- print("整理完成!")
- org = FileOrganizer("D:/下载")
- org.preview()
- org.organize()
复制代码
总结
日常文件整理最常用的三个场景:batch_rename(批量重命名)、auto_sort_files(按类型归档)、find_duplicates(查找重复)。务必先用 dry_run=True 预览效果,确认无误后再执行删除或移动操作。以上所有脚本均基于 Python 3 标准库,无需额外安装第三方包,可在任意环境下直接运行。 |