Статья Сортируем файлы с помощью библиотеки pathlib в Python. Практический пример применения

У каждого из нас в какой-либо из папок скапливается большое количество файлов, рассортировать которые все никак не доходят руки. Мне приходилось наблюдать папку «Загрузки» забитую неимоверным количеством файлов, «Рабочие столы», фото на которых лежит почти друг на друге. И у меня иногда скапливаются файлы, на сортировку которых уходит время. А что, если написать небольшой скрипт на Python, который рассортирует файлы по расширениям и разложит по папкам, попутно удалив пустые директории автоматически? Давайте сделаем это.

000.jpg

Думаю, что не сделаю никаких открытий, сказав, что рассортировать файлы можно с использованием одной библиотеки pathlib, а точнее, ее модуля Path. Каюсь, до недавнего времени, почему-то не обращал на эту библиотеку должного внимания. Может быть потому, что она не представляет из себя ничего экзотического. Но, вот попалась она мне на глаза и попробовав с ней работать я понял, насколько это удобнее, когда идет работа с файлами, чем использовать модуль os. С помощью данного модуля можно получить как полный путь к файлу, так и его расширение, имя, просто путь к папке с файлом и многое другое. А также выполнять базовые операции по удалению, переименованию и перемещению файлов.

Данная заметка, это скорее пример использования данного модуля в практических целях. Ну и кто знает, может быть данный код будет кому-нибудь полезен.


Что потребуется?

Для того, чтобы написать данный скрипт не потребуется скачивать никаких сторонних библиотек, так как библиотека pathlib является предустановленной вместе с Python. Поэтому, нам нужно ее только импортировать в наш скрипт.

from pathlib import Path

Создаем словарь с названиями директорий и расширениями привязанными к ним. Ключом в данном словаре будет название директории, например: «Images», а значением список с расширениями: [".pdf"]. В полном виде данный словарь будет выглядеть вот так:

Python:
dir_suff_dict = {"Images": ['.jpg', '.jpeg', '.png', '.gif', '.tiff', '.ico', '.bmp', '.webp', '.svg'],
                 "Documents": [".md", ".epub", ".txt", ".docx", ".doc", ".ods", ".odt", ".dotx", ".docm", ".dox",
                               ".rvg", ".rtf", ".rtfd", ".wpd", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".xml"],
                 "Archives": [".iso", ".tar", ".gz", ".7z", ".dmg", ".rar", ".zip"],
                 "Audio": [".aac", ".m4a", ".mp3", "ogg", ".raw", ".wav", ".wma"],
                 "Video": [".avi", ".flv", ".wmv", ".mov", ".mp4", ".webm", ".vob", ".mpg", ".mpeg", ".3gp"],
                 "PDF": [".pdf"],
                 "HTML": [".html", ".htm", ".xhtml"],
                 "EXE_MSI": [".exe", ".msi"],
                 "PYTHON": [".py", ".pyw"]}

Конечно же, вы можете самостоятельно добавить директории, а также типы файлов которые нужно будет в них отсортировать. И это, по сути, самая трудоемкая часть данного скрипта.
Теперь создадим функцию, которая на входе будет принимать путь к директории, в которой нужно сортировать файлы. Назову ее: sort_func(path_dir).
Для начала создам переменную, которая будет хранить путь к целевой директории, преобразованной с помощью модуля Path.

Python:
cur_dir = Path(path_dir)

Теперь запускаю цикл по целевой директории, из которой, с помощью функции iterdir() получаю список файлов. В данном случае переменная file будет содержать полный путь к файлу в директории.

Python:
for file in cur_dir.iterdir():

Затем проверяю, является ли объект полученный в цикле папкой, ведь в директории могут содержаться не только файлы. Проверяю размер папки, и если он равен 0, значит она пустая, а следовательно, ее можно удалить. Что и делается с помощью функции rmdir().

Python:
        if file.is_dir():
            if file.stat().st_size == 0:
                file.rmdir()

Запускаю еще один цикл, в котором уже перебираю содержимое созданного ранее словаря с директориями и расширениями. Проверяю, содержится ли расширение файла в директории в списке ключа.

Python:
        for suff in dir_suff_dict:
            if file.suffix.lower() in dir_suff_dict[suff]:

Если да, создаем директорию с названием ключа. Здесь не требуется проверки на наличие или отсутствие директории. Все дело в ключе exist_ok=True, который позволяет игнорировать исключение FileExistsError возникающее, если директория уже существует. И затем, перемещаю текущий файл в только что созданную директорию, где в качестве пути, куда перемещать файл указывается имя созданной директории объединенное с именем файла, который нужно переместить.

Python:
                dir_img = cur_dir / suff
                dir_img.mkdir(exist_ok=True)
                file.rename(dir_img.joinpath(file.name))

Полный код функции сортировки файлов:

Python:
def sort_func(path_dir):
    cur_dir = Path(path_dir)
    for file in cur_dir.iterdir():
        if file.is_dir():
            if file.stat().st_size == 0:
                file.rmdir()
        for suff in dir_suff_dict:
            if file.suffix.lower() in dir_suff_dict[suff]:
                dir_img = cur_dir / suff
                dir_img.mkdir(exist_ok=True)
                file.rename(dir_img.joinpath(file.name))

Ну и код для запуска функции. Для начала запрашиваем у пользователя путь к директории для сортировки. Проверяем, существует ли данная директория. Если нет, сообщаем об этом пользователю. Если да, запускаем функцию сортировки, в которую передаем путь к директории. А по окончании сортировки сообщаем об этом пользователю.

Python:
if __name__ == "__main__":
    path_d = input('[+] Введите путь к директории для сортировки: ')
    if not Path(path_d).exists():
        print('[-] Директории не существует')
    else:
        sort_func(path_d)
    print('[!] Сортировка завершена')

Вот в принципе и все. Хочу сказать, что по удобству работы с файлами данная библиотека намного превосходит библиотеку os. Конечно же, это не говорит о том, что она ее полностью заменяет. Но, могу сказать, что если раньше я, можно сказать, мучился, когда мне нужно было получить расширение файла или его имя без расширения, то теперь, сделать это легко и просто. Одно могу сказать точно, на данную библиотеку нужно было обратить внимание еще раньше.

Но, к моему сожалению, не скажу за всех, но в тех видео и книгах для новичков почему-то очень подробно рассматривается библиотека os, а вот упоминание о pathlib я почти не встречал. По крайней мере, не помню об этом. Встречал данную библиотеку в статьях, но почему-то считал ее сторонней.

Ну и демонстрация работы библиотеки. Вот как выглядела директория до сортировки:

dir01.png

А так уже после:

dir02.png

Python:
from pathlib import Path

dir_suff_dict = {"Images": ['.jpg', '.jpeg', '.png', '.gif', '.tiff', '.ico', '.bmp', '.webp', '.svg'],
                 "Documents": [".md", ".epub", ".txt", ".docx", ".doc", ".ods", ".odt", ".dotx", ".docm", ".dox",
                               ".rvg", ".rtf", ".rtfd", ".wpd", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".xml"],
                 "Archives": [".iso", ".tar", ".gz", ".7z", ".dmg", ".rar", ".zip"],
                 "Audio": [".aac", ".m4a", ".mp3", "ogg", ".raw", ".wav", ".wma"],
                 "Video": [".avi", ".flv", ".wmv", ".mov", ".mp4", ".webm", ".vob", ".mpg", ".mpeg", ".3gp"],
                 "PDF": [".pdf"],
                 "HTML": [".html", ".htm", ".xhtml"],
                 "EXE_MSI": [".exe", ".msi"],
                 "PYTHON": [".py", ".pyw"]}


def sort_func(path_dir):
    cur_dir = Path(path_dir)
    for file in cur_dir.iterdir():
        if file.is_dir():
            if file.stat().st_size == 0:
                file.rmdir()
        for suff in dir_suff_dict:
            if file.suffix.lower() in dir_suff_dict[suff]:
                dir_img = cur_dir / suff
                dir_img.mkdir(exist_ok=True)
                file.rename(dir_img.joinpath(file.name))


if __name__ == "__main__":
    path_d = input('[+] Введите путь к директории для сортировки: ')
    if not Path(path_d).exists():
        print('[-] Директории не существует')
    else:
        sort_func(path_d)
    print('[!] Сортировка завершена')

А на этом, пожалуй, все.

Спасибо за внимание. Надеюсь, что данная информация будет вам полезна
 

Johan Van

Green Team
13.06.2020
363
691
BIT
394
У каждого из нас в какой-либо из папок скапливается большое количество файлов, рассортировать которые все никак не доходят руки. Мне приходилось наблюдать папку «Загрузки» забитую неимоверным количеством файлов, «Рабочие столы», фото на которых лежит почти друг на друге. И у меня иногда скапливаются файлы, на сортировку которых уходит время. А что, если написать небольшой скрипт на Python, который рассортирует файлы по расширениям и разложит по папкам, попутно удалив пустые директории автоматически? Давайте сделаем это.


Думаю, что не сделаю никаких открытий, сказав, что рассортировать файлы можно с использованием одной библиотеки pathlib, а точнее, ее модуля Path. Каюсь, до недавнего времени, почему-то не обращал на эту библиотеку должного внимания. Может быть потому, что она не представляет из себя ничего экзотического. Но, вот попалась она мне на глаза и попробовав с ней работать я понял, насколько это удобнее, когда идет работа с файлами, чем использовать модуль os. С помощью данного модуля можно получить как полный путь к файлу, так и его расширение, имя, просто путь к папке с файлом и многое другое. А также выполнять базовые операции по удалению, переименованию и перемещению файлов.

Данная заметка, это скорее пример использования данного модуля в практических целях. Ну и кто знает, может быть данный код будет кому-нибудь полезен.


Что потребуется?

Для того, чтобы написать данный скрипт не потребуется скачивать никаких сторонних библиотек, так как библиотека pathlib является предустановленной вместе с Python. Поэтому, нам нужно ее только импортировать в наш скрипт.

from pathlib import Path

Создаем словарь с названиями директорий и расширениями привязанными к ним. Ключом в данном словаре будет название директории, например: «Images», а значением список с расширениями: [".pdf"]. В полном виде данный словарь будет выглядеть вот так:

Python:
dir_suff_dict = {"Images": ['.jpg', '.jpeg', '.png', '.gif', '.tiff', '.ico', '.bmp', '.webp', '.svg'],
                 "Documents": [".md", ".epub", ".txt", ".docx", ".doc", ".ods", ".odt", ".dotx", ".docm", ".dox",
                               ".rvg", ".rtf", ".rtfd", ".wpd", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".xml"],
                 "Archives": [".iso", ".tar", ".gz", ".7z", ".dmg", ".rar", ".zip"],
                 "Audio": [".aac", ".m4a", ".mp3", "ogg", ".raw", ".wav", ".wma"],
                 "Video": [".avi", ".flv", ".wmv", ".mov", ".mp4", ".webm", ".vob", ".mpg", ".mpeg", ".3gp"],
                 "PDF": [".pdf"],
                 "HTML": [".html", ".htm", ".xhtml"],
                 "EXE_MSI": [".exe", ".msi"],
                 "PYTHON": [".py", ".pyw"]}

Конечно же, вы можете самостоятельно добавить директории, а также типы файлов которые нужно будет в них отсортировать. И это, по сути, самая трудоемкая часть данного скрипта.
Теперь создадим функцию, которая на входе будет принимать путь к директории, в которой нужно сортировать файлы. Назову ее: sort_func(path_dir).
Для начала создам переменную, которая будет хранить путь к целевой директории, преобразованной с помощью модуля Path.

Python:
cur_dir = Path(path_dir)

Теперь запускаю цикл по целевой директории, из которой, с помощью функции iterdir() получаю список файлов. В данном случае переменная file будет содержать полный путь к файлу в директории.

Python:
for file in cur_dir.iterdir():

Затем проверяю, является ли объект полученный в цикле папкой, ведь в директории могут содержаться не только файлы. Проверяю размер папки, и если он равен 0, значит она пустая, а следовательно, ее можно удалить. Что и делается с помощью функции rmdir().

Python:
        if file.is_dir():
            if file.stat().st_size == 0:
                file.rmdir()

Запускаю еще один цикл, в котором уже перебираю содержимое созданного ранее словаря с директориями и расширениями. Проверяю, содержится ли расширение файла в директории в списке ключа.

Python:
        for suff in dir_suff_dict:
            if file.suffix.lower() in dir_suff_dict[suff]:

Если да, создаем директорию с названием ключа. Здесь не требуется проверки на наличие или отсутствие директории. Все дело в ключе exist_ok=True, который позволяет игнорировать исключение FileExistsError возникающее, если директория уже существует. И затем, перемещаю текущий файл в только что созданную директорию, где в качестве пути, куда перемещать файл указывается имя созданной директории объединенное с именем файла, который нужно переместить.

Python:
                dir_img = cur_dir / suff
                dir_img.mkdir(exist_ok=True)
                file.rename(dir_img.joinpath(file.name))

Полный код функции сортировки файлов:

Python:
def sort_func(path_dir):
    cur_dir = Path(path_dir)
    for file in cur_dir.iterdir():
        if file.is_dir():
            if file.stat().st_size == 0:
                file.rmdir()
        for suff in dir_suff_dict:
            if file.suffix.lower() in dir_suff_dict[suff]:
                dir_img = cur_dir / suff
                dir_img.mkdir(exist_ok=True)
                file.rename(dir_img.joinpath(file.name))

Ну и код для запуска функции. Для начала запрашиваем у пользователя путь к директории для сортировки. Проверяем, существует ли данная директория. Если нет, сообщаем об этом пользователю. Если да, запускаем функцию сортировки, в которую передаем путь к директории. А по окончании сортировки сообщаем об этом пользователю.

Python:
if __name__ == "__main__":
    path_d = input('[+] Введите путь к директории для сортировки: ')
    if not Path(path_d).exists():
        print('[-] Директории не существует')
    else:
        sort_func(path_d)
    print('[!] Сортировка завершена')

Вот в принципе и все. Хочу сказать, что по удобству работы с файлами данная библиотека намного превосходит библиотеку os. Конечно же, это не говорит о том, что она ее полностью заменяет. Но, могу сказать, что если раньше я, можно сказать, мучился, когда мне нужно было получить расширение файла или его имя без расширения, то теперь, сделать это легко и просто. Одно могу сказать точно, на данную библиотеку нужно было обратить внимание еще раньше.

Но, к моему сожалению, не скажу за всех, но в тех видео и книгах для новичков почему-то очень подробно рассматривается библиотека os, а вот упоминание о pathlib я почти не встречал. По крайней мере, не помню об этом. Встречал данную библиотеку в статьях, но почему-то считал ее сторонней.

Ну и демонстрация работы библиотеки. Вот как выглядела директория до сортировки:


А так уже после:


Python:
from pathlib import Path

dir_suff_dict = {"Images": ['.jpg', '.jpeg', '.png', '.gif', '.tiff', '.ico', '.bmp', '.webp', '.svg'],
                 "Documents": [".md", ".epub", ".txt", ".docx", ".doc", ".ods", ".odt", ".dotx", ".docm", ".dox",
                               ".rvg", ".rtf", ".rtfd", ".wpd", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".xml"],
                 "Archives": [".iso", ".tar", ".gz", ".7z", ".dmg", ".rar", ".zip"],
                 "Audio": [".aac", ".m4a", ".mp3", "ogg", ".raw", ".wav", ".wma"],
                 "Video": [".avi", ".flv", ".wmv", ".mov", ".mp4", ".webm", ".vob", ".mpg", ".mpeg", ".3gp"],
                 "PDF": [".pdf"],
                 "HTML": [".html", ".htm", ".xhtml"],
                 "EXE_MSI": [".exe", ".msi"],
                 "PYTHON": [".py", ".pyw"]}


def sort_func(path_dir):
    cur_dir = Path(path_dir)
    for file in cur_dir.iterdir():
        if file.is_dir():
            if file.stat().st_size == 0:
                file.rmdir()
        for suff in dir_suff_dict:
            if file.suffix.lower() in dir_suff_dict[suff]:
                dir_img = cur_dir / suff
                dir_img.mkdir(exist_ok=True)
                file.rename(dir_img.joinpath(file.name))


if __name__ == "__main__":
    path_d = input('[+] Введите путь к директории для сортировки: ')
    if not Path(path_d).exists():
        print('[-] Директории не существует')
    else:
        sort_func(path_d)
    print('[!] Сортировка завершена')

А на этом, пожалуй, все.

Спасибо за внимание. Надеюсь, что данная информация будет вам полезна

Думаю, что по истечении времени стали видны ошибки и недочеты данного кода. В данном случае, нет возможности провести сортировку вложенных папок, так как функция не обходит их рекурсивно. В общем, немного доработав данный код, в итоге получил вот что:

Python:
import os
import re
from pathlib import Path

dir_suf_dict = {"Images": ['.jpg', '.jpeg', '.png', '.gif', '.tiff', '.ico', '.bmp', '.webp', '.svg'],
                "Documents": [".md", ".epub", ".txt", ".docx", ".doc", ".ods", ".odt", ".dotx", ".docm", ".dox",
                              ".rvg", ".rtf", ".rtfd", ".wpd", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".xml"],
                "Archives": [".iso", ".tar", ".gz", ".7z", ".dmg", ".rar", ".zip"],
                "Audio": [".aac", ".m4a", ".mp3", "ogg", ".raw", ".wav", ".wma"],
                "Video": [".avi", ".flv", ".wmv", ".mov", ".mp4", ".webm", ".vob", ".mpg", ".mpeg", ".3gp"],
                "PDF": [".pdf"],
                "HTML": [".html", ".htm", ".xhtml"],
                "EXE_MSI": [".exe", ".msi"],
                "PYTHON": [".py", ".pyw"]}


def normalize(name: str) -> str:
    cyrillic_symbols = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'
    translation = (
        "a", "b", "v", "g", "d", "e", "e", "j", "z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u",
        "f", "h", "ts", "ch", "sh", "sch", "", "y", "", "e", "yu", "u", "ja")

    trans = {}
    for c, l in zip(cyrillic_symbols, translation):
        trans[ord(c)] = l
        trans[ord(c.upper())] = l.upper()
    t_name = name.translate(trans)
    t_name = re.sub(r'\W', '_', t_name)
    return t_name


def move_file(dir_p: Path, path_file: Path):
    """
    Создается папка с названием группы расширений.
    Перемещается текущий файл в созданную папку.
    :param dir_p: объект Path для создания папки.
    :param path_file: объект Path содержащий путь к файлу.
    """
    dir_p.mkdir(exist_ok=True)
    if (Path(dir_p) / path_file.name).exists():
        path_file.rename(dir_p.joinpath(f'{path_file.name[0:-len(path_file.suffix)]}_c{path_file.suffix}'))
        print(f"Возможно дубликат: {path_file.name}")
    else:
        path_file.rename(dir_p / path_file.name)


def extension_comparison(curr_dir: Path, path_file: Path, suf: str) -> bool:
    """
    Выполняется проверка, входит ли расширение текущего файла
    хотя бы в одну из групп представленных в словаре. Если входит -
    возвращается True, нет - False.
    :param curr_dir: объект Path с путем к директории проверки.
    :param path_file: объект Path с путем к текущему файлу.
    :param suf: строка, содержащая ключ из словаря с группами расширений.
    :return: True или False, в зависимости от результатов проверки.
    """
    if path_file.suffix in dir_suf_dict[suf]:
        move_file(Path(curr_dir) / suf, path_file)
        return True
    return False


def name_normalize(root: str, file: str) -> Path:
    """
    Нормализации (приведение к нужному виду, то есть, в данном случае
    замена кириллицы на латинские буквы).
    Переименование текущего файла в соответствии с результатами нормализации.
    :param root: строка с путем к текущему файлу.
    :param file: имя текущего файла с расширением.
    :return: объект Path с путем к переименованному файлу.
    """
    path_file = Path(root) / file
    normalize_n = f"{normalize(path_file.name[0:-len(path_file.suffix)])}{path_file.suffix}"
    path_file = path_file.rename(Path(root) / normalize_n)
    return path_file


def remove_dir(subdir: list):
    """
    Удаление пустых директорий, которые остались
    после перемещения из них файлов при сортировке.
    :param subdir: список с абсолютными путями к удаляемым директориям.
    """
    for path in subdir:
        if len(os.listdir(path)) > 0 or Path(path).name in dir_suf_dict:
            continue
        Path(path).rmdir()


def sort_func(path_d: str) -> tuple:
    """
    Сортировка файлов на основе расширения, а также вхождении
    расширения в одну из групп из словаря.
    Создаются списки с начальными поддиректориями в директории сортировки.
    Нормализация (замена кириллицы на латиницу) имен файлов.
    Проверка принадлежности расширения файла к одной из групп словаря.
    Перемещение в соответствии с принадлежностью к группе или, если принадлежности
    к группе не найдено, в папку "Other".
    Удаление пустых папок после сортировки.
    :param path_d: строка содержащая путь к директории для сортировки.
    :return: кортеж из списков с распознанными и не распознанными расширениями.
    """
    curr_dir = Path(path_d)
    subdir = []
    known_extensions, unknown_extensions = set(), set()
    for root, dirs, files in os.walk(path_d):
        for d in dirs:
            if not d:
                continue
            subdir.append(f"{curr_dir / d}")
        for file in files:
            path_file = name_normalize(root, file)
            ex_comp = False
            for suf in dir_suf_dict:
                ex_comp = extension_comparison(curr_dir, path_file, suf)
                if ex_comp:
                    known_extensions.add(path_file.suffix)
                    break
            if not ex_comp:
                move_file(Path(curr_dir) / "Other", path_file)
                unknown_extensions.add(path_file.suffix)

    remove_dir(subdir)
    return list(known_extensions), list(unknown_extensions)


def main():
    """
    Запрос у пользователя директории для сортировки файлов.
    Проверка директории на существование.
    Запуск функции сортировки с передачей полученного от пользователя пути.
    Проверка количества элементов в возвращенных словарях. Если кол-во элементов
    меньше или равно 0, сообщение не печатается. Если больше нуля, то
    выводиться в терминал список полученный после работы функции сортировки.
    """
    known, unknown = "", ""
    path_d = input('[+] Введите путь к директории для сортировки: ')
    if not Path(path_d).exists():
        print('[-] Директории не существует')
    else:
        known, unknown = sort_func(path_d)

    if len(known) >= 0:
        print(f"\nРаспознанные расширения:\n{known}")
    if len(unknown) >= 0:
        print(f"Не распознанные расширения:\n{unknown}")

    print('[!] Сортировка завершена')


if __name__ == "__main__":
    main()

Спасибо пользователю doS100 за вопросы по сортировке. С его подачи данный код дополнился также функцией замены кириллицы в именах файлов, на латиницу. Функция нормализации предложена им.
 
Последнее редактирование:

Alex Tremer

New member
25.01.2023
1
0
BIT
0
Вот код с добавленной функцией нормализации:

Python:
import os
import re
from pathlib import Path

dir_suff_dict = {"Images": ['.jpg', '.jpeg', '.png', '.gif', '.tiff', '.ico', '.bmp', '.webp', '.svg'],
                 "Documents": [".md", ".epub", ".txt", ".docx", ".doc", ".ods", ".odt", ".dotx", ".docm", ".dox",
                               ".rvg", ".rtf", ".rtfd", ".wpd", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".xml"],
                 "Archives": [".iso", ".tar", ".gz", ".7z", ".dmg", ".rar", ".zip"],
                 "Audio": [".aac", ".m4a", ".mp3", "ogg", ".raw", ".wav", ".wma"],
                 "Video": [".avi", ".flv", ".wmv", ".mov", ".mp4", ".webm", ".vob", ".mpg", ".mpeg", ".3gp"],
                 "PDF": [".pdf"],
                 "HTML": [".html", ".htm", ".xhtml"],
                 "EXE_MSI": [".exe", ".msi"],
                 "PYTHON": [".py", ".pyw"]}


def normalize(name: str) -> str:
    CYRILLIC_SYMBOLS = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'
    TRANSLATION = (
    "a", "b", "v", "g", "d", "e", "e", "j", "z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u",
    "f", "h", "ts", "ch", "sh", "sch", "", "y", "", "e", "yu", "u", "ja")

    TRANS = {}
    for c, l in zip(CYRILLIC_SYMBOLS, TRANSLATION):
        TRANS[ord(c)] = l
        TRANS[ord(c.upper())] = l.upper()
    t_name = name.translate(TRANS)
    t_name = re.sub(r'\W', '_', t_name)
    return t_name


def sort_func(path_dir):
    cur_dir = Path(path_dir)
    dir_path = []

    for root, dirs, files in os.walk(path_dir):
        for d in dirs:
            dir_path.append(os.path.join(root, d))
        for file in files:
            p_file = Path(root) / file
            name_normalize = f"{normalize(p_file.name[0:-len(p_file.suffix)])}{p_file.suffix}"
            p_file.rename(Path(root) / name_normalize)
            p_file = Path(root) / name_normalize
            for suff in dir_suff_dict:
                if p_file.suffix.lower() in dir_suff_dict[suff]:
                    dir_img = cur_dir / suff
                    dir_img.mkdir(exist_ok=True)
                    try:
                        p_file.rename(dir_img.joinpath(p_file.name))
                    except FileExistsError:
                        p_file.rename(dir_img.joinpath(f'{p_file.name.split(".")[0]}_c{p_file.suffix}'))
                        print(f"Возможно дубликат: {p_file.name}")

    for dir_p in reversed(dir_path):
        if os.path.split(dir_p)[1] in dir_suff_dict or os.stat(dir_p).st_size != 0:
            continue
        else:
            os.rmdir(dir_p)


if __name__ == "__main__":
    path_d = input('[+] Введите путь к директории для сортировки: ')
    if not Path(path_d).exists():
        print('[-] Директории не существует')
    else:
        sort_func(path_d)
    print('[!] Сортировка завершена')

Для примера:




Вроде работает )) Сильно тестировать пока некогда ))

В данном коде добавилась ваша функция и вот эти вот строчки:

Python:
            name_normalize = f"{normalize(p_file.name[0:-len(p_file.suffix)])}{p_file.suffix}"
            p_file.rename(Path(root) / name_normalize)
            p_file = Path(root) / name_normalize
Добрый день! пытаюсь добавить в Ваш код еще несколько условий
  • скрипт игнорирует папки archives, video, audio, documents, images;
  • распакованное содержимое архива переносится в папку archives в подпапку, названную точно так же, как и архив, но без расширения в конце;
  • файлы, расширения которых неизвестны, остаются без изменений.

но пока столкнулся с проблемой работы с архивами.
Если у вас будет возможность подсказать как это реализовать, буду очень благодарен
 

Johan Van

Green Team
13.06.2020
363
691
BIT
394
Добрый день! пытаюсь добавить в Ваш код еще несколько условий
  • скрипт игнорирует папки archives, video, audio, documents, images;
  • распакованное содержимое архива переносится в папку archives в подпапку, названную точно так же, как и архив, но без расширения в конце;
  • файлы, расширения которых неизвестны, остаются без изменений.

но пока столкнулся с проблемой работы с архивами.
Если у вас будет возможность подсказать как это реализовать, буду очень благодарен

Добрый день. Если вам не трудно, пришлите ваш код мне в личку. Я чуть позже, как освобожусь, его посмотрю.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!