本文目录导读:

我来帮你编写一个文件移动分类脚本,这里提供几个不同场景的版本:
按文件扩展名分类
import os
import shutil
from pathlib import Path
def organize_by_extension(source_dir, target_dir=None):
"""
按文件扩展名分类移动文件
"""
source_path = Path(source_dir)
if target_dir is None:
target_dir = source_dir
target_path = Path(target_dir)
# 定义常见文件类型的扩展名
extension_categories = {
'Images': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'],
'Documents': ['.pdf', '.doc', '.docx', '.txt', '.xlsx', '.pptx', '.md'],
'Videos': ['.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv'],
'Audio': ['.mp3', '.wav', '.flac', '.aac', '.ogg'],
'Archives': ['.zip', '.rar', '.7z', '.tar', '.gz'],
'Code': ['.py', '.js', '.html', '.css', '.java', '.cpp', '.h']
}
# 创建文件夹并移动文件
for file in source_path.iterdir():
if file.is_file():
moved = False
for category, extensions in extension_categories.items():
if file.suffix.lower() in extensions:
category_path = target_path / category
category_path.mkdir(exist_ok=True)
dest = category_path / file.name
# 处理同名文件
if dest.exists():
base = file.stem
counter = 1
while dest.exists():
dest = category_path / f"{base}_{counter}{file.suffix}"
counter += 1
shutil.move(str(file), str(dest))
print(f"移动: {file.name} -> {category}/")
moved = True
break
if not moved:
other_path = target_path / 'Others'
other_path.mkdir(exist_ok=True)
shutil.move(str(file), str(other_path / file.name))
print(f"移动: {file.name} -> Others/")
# 使用示例
organize_by_extension('./downloads', './organized')
按文件日期分类
import os
import shutil
from pathlib import Path
import datetime
def organize_by_date(source_dir, target_dir=None):
"""
按文件创建/修改日期分类(按年月)
"""
source_path = Path(source_dir)
if target_dir is None:
target_dir = source_dir
target_path = Path(target_dir)
for file in source_path.iterdir():
if file.is_file():
# 获取文件的最后修改时间
mtime = os.path.getmtime(file)
date = datetime.datetime.fromtimestamp(mtime)
# 创建年月文件夹
year_month = f"{date.year}-{date.month:02d}"
date_path = target_path / year_month
date_path.mkdir(exist_ok=True)
# 移动文件
dest = date_path / file.name
if dest.exists():
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
dest = date_path / f"{file.stem}_{timestamp}{file.suffix}"
shutil.move(str(file), str(dest))
print(f"移动: {file.name} -> {year_month}/")
# 使用示例
organize_by_date('./photos', './sorted_photos')
按文件大小分类
import os
import shutil
from pathlib import Path
def organize_by_size(source_dir, target_dir=None):
"""
按文件大小分类
"""
source_path = Path(source_dir)
if target_dir is None:
target_dir = source_dir
target_path = Path(target_dir)
# 定义大小类别(字节)
size_categories = {
'Small': (0, 1024 * 100), # 小于100KB
'Medium': (1024 * 100, 1024 * 1024), # 100KB - 1MB
'Large': (1024 * 1024, 1024 * 1024 * 100), # 1MB - 100MB
'Very_Large': (1024 * 1024 * 100, float('inf')) # 大于100MB
}
for file in source_path.iterdir():
if file.is_file():
file_size = file.stat().st_size
for category, (min_size, max_size) in size_categories.items():
if min_size <= file_size < max_size:
category_path = target_path / category
category_path.mkdir(exist_ok=True)
dest = category_path / file.name
if dest.exists():
base = file.stem
counter = 1
while dest.exists():
dest = category_path / f"{base}_{counter}{file.suffix}"
counter += 1
shutil.move(str(file), str(dest))
size_str = f"{file_size/1024:.2f}KB" if file_size < 1024*1024 else f"{file_size/(1024*1024):.2f}MB"
print(f"移动: {file.name} ({size_str}) -> {category}/")
break
# 使用示例
organize_by_size('./downloads', './sorted_by_size')
高级综合版本(带命令行参数)
import os
import shutil
from pathlib import Path
import argparse
import datetime
import re
class FileOrganizer:
def __init__(self, source_dir, target_dir=None, dry_run=False, pattern=None):
self.source = Path(source_dir)
self.target = Path(target_dir) if target_dir else self.source
self.dry_run = dry_run
self.pattern = re.compile(pattern) if pattern else None
self.stats = {'moved': 0, 'skipped': 0, 'errors': 0}
def organize_by_extension(self):
"""按扩展名组织文件"""
ext_map = {
'Images': ['.jpg', '.jpeg', '.png', '.gif', '.bmp'],
'Documents': ['.pdf', '.doc', '.docx', '.txt', '.md'],
'Videos': ['.mp4', '.avi', '.mkv', '.mov'],
'Audio': ['.mp3', '.wav', '.flac', '.aac'],
'Archives': ['.zip', '.rar', '.7z', '.tar', '.gz']
}
for file in self.source.iterdir():
if self._should_process(file):
target_folder = 'Others'
for category, extensions in ext_map.items():
if file.suffix.lower() in extensions:
target_folder = category
break
self._move_file(file, self.target / target_folder)
def organize_by_date(self):
"""按日期组织文件"""
for file in self.source.iterdir():
if self._should_process(file):
mtime = os.path.getmtime(file)
date = datetime.datetime.fromtimestamp(mtime)
folder_name = f"{date.year}-{date.month:02d}"
self._move_file(file, self.target / folder_name)
def _should_process(self, file):
"""检查文件是否应该被处理"""
if not file.is_file():
return False
if self.pattern and not self.pattern.search(file.name):
return False
return True
def _move_file(self, file, target_folder):
"""移动文件到目标文件夹"""
try:
target_folder.mkdir(parents=True, exist_ok=True)
dest = target_folder / file.name
# 处理重名文件
if dest.exists():
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
dest = target_folder / f"{file.stem}_{timestamp}{file.suffix}"
if self.dry_run:
print(f"[模拟] 移动: {file.name} -> {target_folder.name}/")
self.stats['moved'] += 1
else:
shutil.move(str(file), str(dest))
print(f"移动: {file.name} -> {target_folder.name}/")
self.stats['moved'] += 1
except Exception as e:
print(f"错误: 无法移动 {file.name}: {e}")
self.stats['errors'] += 1
def print_stats(self):
"""打印统计信息"""
print(f"\n统计信息:")
print(f"✅ 成功移动: {self.stats['moved']} 个文件")
print(f"❌ 错误: {self.stats['errors']} 个")
print(f"⏭️ 跳过: {self.stats['skipped']} 个")
def main():
parser = argparse.ArgumentParser(description='文件分类移动脚本')
parser.add_argument('source', help='源文件夹路径')
parser.add_argument('-t', '--target', help='目标文件夹路径(默认为源文件夹)')
parser.add_argument('-m', '--method', choices=['ext', 'date', 'size'],
default='ext', help='分类方法(ext:按扩展名, date:按日期, size:按大小)')
parser.add_argument('--dry-run', action='store_true', help='模拟运行,不实际移动文件')
parser.add_argument('-p', '--pattern', help='文件匹配模式(正则表达式)')
args = parser.parse_args()
organizer = FileOrganizer(
source_dir=args.source,
target_dir=args.target,
dry_run=args.dry_run,
pattern=args.pattern
)
print(f"开始整理文件...")
print(f"源文件夹: {organizer.source}")
print(f"目标文件夹: {organizer.target}")
if args.dry_run:
print("⚠️ 模拟运行模式,不会实际移动文件")
if args.method == 'ext':
organizer.organize_by_extension()
elif args.method == 'date':
organizer.organize_by_date()
# 添加更多方法...
organizer.print_stats()
if __name__ == "__main__":
main()
使用方式
基本使用
# 按扩展名分类 python file_organizer.py ./downloads # 按日期分类 python file_organizer.py ./downloads -m date # 指定目标文件夹 python file_organizer.py ./downloads -t ./organized # 模拟运行(不实际移动文件) python file_organizer.py ./downloads --dry-run # 只处理特定文件 python file_organizer.py ./downloads -p ".*\.(jpg|png|gif)$"
安全建议
- 先测试:先用
--dry-run模拟运行 - 备份重要文件:分类前最好备份
- 不要移动系统文件:避免破坏系统结构
- 注意路径:使用绝对路径要小心
需要根据你的具体需求调整代码,有什么特定需求吗?