Автоматическая сортировка файлов на Python: из хаоса в порядок одной командой

от автора

Привет, Хабр! Думаю, всем знакома ситуация: десятки файлов на рабочем столе, сваленных в единую кучу. Скрины, документы, архивы — и всё в одном рабочем пространстве. Наводить порядок не всегда получается, а жить в беспорядке не очень удобно. Недавно, в процессе наведения порядка, я утомился делать это руками и очень захотел написать скрипт на Python, который структурирует и раскидает всё по папкам самостоятельно.

Скрипт в статье:

  • Автоматически сортирует файлы по 9 категориям

  • Поддерживает 50+ форматов файлов

  • Предоставляет гибкие настройки

Введение

Начну с небольшой «демонстрации возможностей» скрипта. Работа со скриптом начинается с настройки конфига, где можно указать не только папку для сортировки, но и некоторые правила, такие как: создание подпапки по дате (полезно для скринов/фото), пропуск скрытых файлов, создание бэкапов, тестовый режим (покажет все действия без реального перемещения), а также возможность добавлять новые расширения и менять структуру сортировки. Всё это подкрепляется логированием.

Сам скрипт:

import os import shutil import argparse from datetime import datetime  def setup_config():     """Настройки по умолчанию с возможностью переопределения"""     return {         # Основные параметры         'target_folder': os.path.expanduser("~/Desktop"),         'log_file': os.path.expanduser("~/Desktop/sort_files.log"),         'date_format': "%Y-%m-%d %H:%M:%S",                  # Правила сортировки (можно расширять, менять и тд.)         'sort_rules': {             "Images": [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg", ".tiff"],             "Documents": [".pdf", ".docx", ".xlsx", ".pptx", ".txt", ".rtf", ".odt", ".csv"],             "Archives": [".zip", ".rar", ".7z", ".tar", ".gz", ".bz2"],             "Media": [".mp3", ".mp4", ".avi", ".mkv", ".mov", ".wav", ".flac"],             "Code": [".py", ".js", ".html", ".css", ".json", ".xml", ".php", ".sh"],             "Executables": [".exe", ".msi", ".dmg", ".pkg", ".deb"],             "Design": [".psd", ".ai", ".sketch", ".fig"],             "Data": [".sql", ".db", ".sqlite", ".mdb"],             "Other": []  # Для нераспознанных расширений         },                  # Дополнительные опции         'create_date_folders': False,  # Создавать подпапки по дате         'skip_hidden': True,           # Пропускать скрытые файлы         'dry_run': False,              # Тестовый режим без реальных действий         'backup_files': False          # Создавать копии перед перемещением     }  def create_folders(target_folder, folders, dry_run=False):     """Создание папки для категорий"""     for folder in folders:         path = os.path.join(target_folder, folder)         if not dry_run:             os.makedirs(path, exist_ok=True)         else:             print(f"[DRY RUN] Создана папка: {path}")  def get_file_category(filename, sort_rules):     """Определение категории файла по его расширению"""     ext = os.path.splitext(filename)[1].lower()     for category, extensions in sort_rules.items():         if ext in extensions:             return category     return "Other"  def backup_file(src, dest, dry_run=False):     """Создание резервной копии файла перед перемещением"""     backup_path = dest + ".backup"     if not dry_run:         shutil.copy2(src, backup_path)     return backup_path  def sort_files(config):     """Основная функция сортировки файлов"""     target_folder = config['target_folder']     sort_rules = config['sort_rules']     folders = list(sort_rules.keys())          # Создание лог-файла     with open(config['log_file'], 'a') as log:         log.write(f"\n=== Сортировка начата: {datetime.now().strftime(config['date_format'])} ===\n")                  # Создание необходимых папок         create_folders(target_folder, folders, config['dry_run'])                  # Обработка файлов         for item in os.listdir(target_folder):             item_path = os.path.join(target_folder, item)                          # Пропуск папок и скрытых файлов (если включено)             if not os.path.isfile(item_path):                 continue             if config['skip_hidden'] and item.startswith('.'):                 continue                          # Определение категории             category = get_file_category(item, sort_rules)                          # Формировка пути назначения             dest_folder = os.path.join(target_folder, category)                          # Опционально: создание подпапки по дате             if config['create_date_folders']:                 today = datetime.now().strftime("%Y-%m-%d")                 dest_folder = os.path.join(dest_folder, today)                 if not config['dry_run']:                     os.makedirs(dest_folder, exist_ok=True)                          dest_path = os.path.join(dest_folder, item)                          # Логирование             action = f"[+] {item} -> {category}"             if config['create_date_folders']:                 action += f"/{today}"             print(action)             log.write(action + "\n")                          # Перемещение (или тестовый режим)             if not config['dry_run']:                 # Создание резервной копии при необходимости                 if config['backup_files']:                     backup_path = backup_file(item_path, dest_path)                     log.write(f"  Создана резервная копия: {backup_path}\n")                                  # Перемещение файла                 try:                     shutil.move(item_path, dest_path)                 except Exception as e:                     error_msg = f"Ошибка при перемещении {item}: {str(e)}"                     print(error_msg)                     log.write(error_msg + "\n")  def main():     """Основная функция с обработкой аргументов командной строки"""     parser = argparse.ArgumentParser(         description="Скрипт для сортировки файлов на рабочем столе по категориям",         epilog="Пример использования: python sort_desktop.py --target ~/Desktop --dry-run"     )          # Аргументы командной строки     parser.add_argument('--target', help="Папка для сортировки (по умолчанию: Desktop)")     parser.add_argument('--log', help="Файл для записи логов")     parser.add_argument('--dry-run', action='store_true', help="Тестовый режим без реальных действий")     parser.add_argument('--date-folders', action='store_true', help="Создавать подпапки по дате")     parser.add_argument('--no-skip-hidden', action='store_true', help="Не пропускать скрытые файлы")     parser.add_argument('--backup', action='store_true', help="Создавать резервные копии файлов")     parser.add_argument('--show-config', action='store_true', help="Показать текущие настройки и выйти")          args = parser.parse_args()          # Загрузка конфигурации     config = setup_config()          # Переопределение настройки из аргументов     if args.target:         config['target_folder'] = os.path.expanduser(args.target)     if args.log:         config['log_file'] = os.path.expanduser(args.log)     if args.dry_run:         config['dry_run'] = True     if args.date_folders:         config['create_date_folders'] = True     if args.no_skip_hidden:         config['skip_hidden'] = False     if args.backup:         config['backup_files'] = True          # Показ конфигурации (если нужно)     if args.show_config:         print("Текущие настройки:")         for key, value in config.items():             print(f"  {key}: {value}")         return          # Запуск сортировки     print("=== Начало сортировки ===")     print(f"Целевая папка: {config['target_folder']}")     print(f"Режим dry-run: {'да' if config['dry_run'] else 'нет'}")          sort_files(config)          print("\n=== Сортировка завершена ===")     print(f"Подробности в лог-файле: {config['log_file']}")  if __name__ == "__main__":     main()

Структура скрипта

Скрипт состоит из нескольких ключевых функций:

  1. setup_config() — инициализация настроек по умолчанию

  2. create_folders() — создание папок для категорий

  3. get_file_category() — определение категории файла по расширению

  4. backup_file() — создание резервной копии файла

  5. sort_files() — основная функция сортировки

  6. main() — обработка аргументов командной строки и запуск процесса

Настройка конфигурации

Функция setup_config() возвращает словарь с настройками:

{     'target_folder': "~/Desktop",  # Папка для сортировки     'log_file': "~/Desktop/sort_files.log",  # Файл для логов     'date_format': "%Y-%m-%d %H:%M:%S",  # Формат даты в логах          # Правила сортировки по расширениям     'sort_rules': {         "Images": [".jpg", ".jpeg", ".png", ...],         "Documents": [".pdf", ".docx", ".xlsx", ...],     },          # Дополнительные опции     'create_date_folders': False,  # Создавать подпапки по дате     'skip_hidden': True,           # Пропускать скрытые файлы     'dry_run': False,              # Тестовый режим     'backup_files': False          # Создавать копии файлов }

Алгоритм работы

  1. Инициализация: загрузка конфигурации, обработка аргументов командной строки

  2. Подготовка: создание папок для всех категорий из sort_rules

  3. Обработка файлов:

    • Для каждого файла в целевой папке определяется категория

    • Формируется путь назначения (с учетом подпапок по дате при необходимости)

    • Создается резервная копия (если включено)

    • Файл перемещается в соответствующую папку

  4. Логирование: все действия записываются в лог-файл

Обработка аргументов командной строки

Скрипт использует модуль argparse для гибкой настройки:

parser = argparse.ArgumentParser(     description="Скрипт для сортировки файлов на рабочем столе по категориям",     epilog="Пример использования: python sort.py --target ~/Desktop --dry-run" )  parser.add_argument('--target', help="Папка для сортировки (по умолчанию: Desktop)") parser.add_argument('--log', help="Файл для записи логов") parser.add_argument('--dry-run', action='store_true', help="Тестовый режим без реальных действий")

Это позволяет легко изменять поведение скрипта без редактирования кода.

Пример и демонстрация использования

Для демонстрации наведу искусственный беспорядок на рабочем столе:

До запуска скрипта

До запуска скрипта

И, командой в cmd (python sort.py — базовая сортировка) запустим скрипт. Результат:

После запуска скрипта

После запуска скрипта

А также, можем заглянуть в файл лога:

Log

Log

Далее, стоит рассмотреть остальные варианты команд. Начнём с тестового запуска для проверки (python sort.py --dry-run):

Тестовый запуск

Тестовый запуск

В данном случае, все наши файлы остались на месте. Данная команда нужна больше для настройки, чтобы ничего случайно не потерять. Далее, рассмотрим сортировку по дате (python sort.py --date-folders):

Сортировка по дате

Сортировка по дате

Папки остались всё те же, но в них появились подпапки с меткой по дате. Выглядит это следующим образом:

Пример результата сортировки по дате

Пример результата сортировки по дате

Аналогично всем инструментам, есть поддержка продвинутых сценариев, пару примеров которых я приведу:

# Сортировка с резервными копиями и подпапками по дате python sort.py --backup --date-folders  # Тестовый прогон для папки "Загрузки" python sort.py --target ~/Downloads --dry-run

Заключение

Представленный в статье скрипт — хорошее решение для тех, кто устал от хаоса на рабочем столе. Он не требует глубоких знаний Python для использования и настройки, но предлагает достаточно широкий функционал по сортировке.

Хочу спросить у сообщества:

  • Какие функции вы бы добавили в подобный инструмент?

  • Интересна ли вам версия с графическим интерфейсом?

  • Стоит ли развивать это решение в полноценный набор инструментов для автоматизации рутины?

Спрашиваю из-за желания изучить создание ПО. В процессе написания скрипта подумал, что добавление GUI/шаблонов/тегов в данном решении смотрелись бы отлично. Да, возможно скрипт не найдет широкого применения и по большей части для многих будет бесполезен, но не поделиться им не мог. Он решил мою вечную проблему свалки.

P.S. В моей группе в Телеграмм разбираем практические кейсы: скрипты (Python/Bash/PowerShell), тонкости ОС и инструменты для эффективной работы.


ссылка на оригинал статьи https://habr.com/ru/articles/935560/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *