Comments 37
В связи с потенциально большим количеством файлов в папке, лучше использовать генераторы
Примерно о таких:
(f.path for f in os.scandir(folder_path) if f.is_dir())
def get_file_paths(folder_path) -> list:
file_paths = [f.path for f in os.scandir(folder_path) if not f.is_dir()]
return file_paths
Если бы это действительно было генератором, выглядело бы оно примерно так.
def get_file_paths(folder_path: str) -> Iterator[str]:
for fn in os.scandir(folder_path):
if not fn.is_dir():
yield fn.path
Работать с путями куда проще и правильней при помощи стандартного os.path.join и os.path.split.
for file_path in file_paths:
for p in subfolder_paths:
Как заставить себя придумывать годные имена для переменных? Чтобы не однобуквенные, но немногословные, друг на друга непохожие, осмысленные, и в одном стиле? ;)
нужно найти какой-то файл. Вот я и подумал, почему бы не написать скрипт сортировщика по расширениям файлов на Python?
Соррян. Так нужно файл найти или отсортировать? Вроде хотели одно, а делаем другое.
У старика Кнута это прям разные главы были. Из того, что я помню, это более эффективный поиск по отсортированной последовательности, но у вас явно не про это.
ЗЫ Вроде в виндоусе есть даже встроенный поиск. Даже я помню вечно тормозящая служба индексера была, да да! Что-то вы странное делаете.
P.S. Вы действительно имели дело с видеофайлами .ts? Я впервые от вас узнал, что такое существует.
Штош. Скорее всего, у многих в папке загрузок собиралась куча разных инсталляторов, архивов и прочих файлов.
Посмотрел бы я как вы запустите инсталлятор, после вашей сортировки, исключение только если инсталлятор идет одним файлом.
По тексту статьи она совсем об другой сортировке, сильно специфичной.
Во первых, если в папке Downloads завелись файлы setup.exe, setup(1).exe.., то самый разумный способ автоматической сортировки - Ctrl+A Del. Никто никогда не вспомнит, что это за инсталляторы. Нет смысла их куда то перекладывать.
Во вторых, если было при скачивании лень нажать save as - значит, скачивалось что то одноразовое. Могу предложить отсортировать файлы по дате и удалить все что старше 1 месяца.
Не забывайте про os.path.join()
@echo off
ROBOCOPY C:\Users\mf\Downloads\ X:\dl\arch *.zip *.7z *.rar *.gz /MOV /IS /minage:1
ROBOCOPY C:\Users\mf\Downloads\ X:\dl\doc *.doc* *.xls* *.pdf *.csv /MOV /IS /minage:1
ROBOCOPY C:\Users\mf\Downloads\ X:\dl\img *.psd /MOV /IS /minage:1
ROBOCOPY C:\Users\mf\Downloads\ X:\dl\soft *.exe *.msi *.cab *.iso *.mdf *.mds /MOV /IS /minage:1
ROBOCOPY C:\Users\mf\Downloads\ X:\dl\media *.mp3 *.wav *.mp4 *.avi /MOV /IS /minage:1
ROBOCOPY C:\Users\mf\Downloads\ X:\dl\book *.fb2 /MOV /IS /minage:1
а если так? не проще…
Для конечного потребителя не проще. В скрипте нужно лишь поменять переменную пути каталога и настроить словарь extensions под свой метод сортировки.
В cmd тоже можно использовать переменные ;) А строк получается значительно меньше. Получается, так проще.
а папка %HOMEPATH%\Downloads обычно является просто свалкой, наравне с %TEMP% и %TMP%
К вашему решению для обычного пользователя осталось добавить gui для настройки и инсталлятор с вэб установщиком интерпретатора.
Это слишком длинный путь ;)
Простой способ решения проблемы файлопомойки - сортировка средствами файл менеджера, перенос нужного, удаление ненужного. Написание кода тут совершенно лишнее. :Ь
Извините, что потратил ваше время на чтение этой статьи и написание 4 комментариев
Предпосылки — 100 гигабайт хранилище, 350 000 файлов, расширения png, gif, ico, jpeg, svg, webp, tiff, pdf, tmp, html, xml, xls, xslx, doc, docx, js, css. Видео ни разу не встречал, хоть и можно. И бесконечное количество файлов с .tmp, .temp или без расширений. Адобовские еще файлы какие то AI, PSD… и т.п.
Сложности:
1. Как уже в комментариях сказали — расширение файла не говорит ничего. Хуже того, если отсортировать картинки по расширению, не проверив, для последующей пакетной обработки, например, в PhotoShop или программно в том же PIL — все упадет. Хорошо так упадет.
Для проверки переимовываем xxxxx.jpg в yyyy.png и открываем в photoshop.
В итоге мы стали использовать Fleep автор Mykyta Paliienko. Эта утилита сообщает о типе файла по содержимому. Кстати пришлось доработать «fleeper» до рабочего состояния, в issue автору тоже сообщили.
2. Файлы с именами, написанными через точку, и без расширений. Отдельная задача, поскольку формально расширение есть.
Решилось так же флиппером.
В коде git статьи extension получается через fp.split('.')[-1], это аналог os.path.splitext(fp) и оба не помогут в решении пункта 2, но os.path.splitext более «кошерный» в случае работы с файловой системой.
3. Также в комментариях сказали про однострочные генераторы. Как в статье так и GIT с примером кода, используются листы или функции генераторов, даже там, где достаточно однострочного генератора, который может делать еще и полезную работу:
# функция def sort_files()
for fp, (file, extention) in (fp.path, os.path.splitext(fp.path) for fp in os.scandir(folder_path) if not fp.is_dir()):
....
Если кого расстраивают длинные строки, например линтер black прям беснуется, то можно так же сделать генераторный pipline:
# функция def sort_files()
path_generator = (_file.path for _file in os.scandir(folder_path) if not _file.is_dir())
extentions_generator = (_path, os.path.splitext(_path) for _path in path_generator)
for path, (file, extention) in extentions_generator:
....
4. Создание папок, и, потом, удаление пустых папок — выглядит вычурно. Если есть словарь хранящий { расширение: путь }, тогда проще получать путь из словаря и создавать путь, если словарь вернул пустое значение.
5. Логирование. Сложная тема. Более 300 000 сообщений одномоментно в консоль бессмыслены и ломали «terminus»- консоль в sublime text.
Решение — использовать стандартный логгер Python c выводом в консоль/файл управляя выводом через атрибуты запуска.
Успехов автору в кодинге.
Сортируем файлы с помощью Python