如何写文件移动分类脚本

wen 实用脚本 30

本文目录导读:

如何写文件移动分类脚本

  1. 按文件扩展名分类
  2. 按文件日期分类
  3. 按文件大小分类
  4. 高级综合版本(带命令行参数)
  5. 使用方式
  6. 安全建议

我来帮你编写一个文件移动分类脚本,这里提供几个不同场景的版本:

按文件扩展名分类

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)$"

安全建议

  1. 先测试:先用 --dry-run 模拟运行
  2. 备份重要文件:分类前最好备份
  3. 不要移动系统文件:避免破坏系统结构
  4. 注意路径:使用绝对路径要小心

需要根据你的具体需求调整代码,有什么特定需求吗?

抱歉,评论功能暂时关闭!