files mess scaled
Многим из нас знакома ситуация, когда компьютер оказывался завален тоннами беспорядочных файлов. Только что вы открывали большой zip-архив, спустя мгновение – файлы повсюду в этой директории, вперемешку с важными документами. Наверняка приходилось мучительно скучно сортировать эту свалку вручную? Чтобы облегчить подобные задачи, мы сейчас погрузимся в «умную» работу с файлами при помощи Python.
«Работай умнее, а не усерднее». Карл Баркс
Итак, приступим, вооружившись Python версии 3.4 или выше. Сначала пройдемся по модулю OS, а по ходу дела познакомимся еще с несколькими. Всё, что мы будем использовать, доступно в Python «с коробки», так что ничего дополнительно устанавливать не потребуется.
Создадим папку ManageFiles, а внутри нее еще одну — RandomFiles. Дерево каталогов теперь должно выглядеть вот так:
ManageFiles/ | |_RandomFiles/
Чтобы поиграться с файлами, мы сгенерируем их случайным образом в директории RandomFiles. Создайте файл create_random_files.py в папке ManageFiles. Вот что должно получиться:
ManageFiles/ | |_ create_random_files.py |_RandomFiles/
Готово? Теперь поместите в файл следующий код, и перейдем к его рассмотрению:
import os
from pathlib import Path
import random
list_of_extensions = ['.rst', '.txt', '.md', '.docx', '.odt', '.html', '.ppt', '.doc']
# перейти в папку RandomFiles
os.chdir('./RandomFiles')
for item in list_of_extensions:
# создать 20 случайных файлов для каждого расширения имени
for num in range(20):
# пусть имя файла начинается со случайного числа от 1 до 50
file_name = random.randint(1, 50)
file_to_create = str(file_name) + item
Path(file_to_create).touch()
Начиная с Python 3.4 мы получили pathlib, нашу маленькую волшебную палочку. Также мы импортируем функцию random для генерации случайных чисел, но ее мы посмотрим в действии чуть ниже.
Сперва создадим список файловых расширений для формирования названий файлов. Не стесняйтесь добавить туда свои варианты.
Далее мы переходим в папку RandomFiles и запускаем цикл. В нем мы просто говорим: возьми каждый элемент list_of_extensions и сделай с ним кое-что во внутреннем цикле 20 раз.
Теперь пришло время для импортированной функции random. Используем ее для производства случайных чисел от 1 до 50. Это просто не очень творческий способ побыстрее дать названия нашим тестовым файлам: к сгенерированному числу добавим расширение файла и получим что-то вроде 23.txt или 14.txt. И так 20 раз для каждого расширения. В итоге образуется беспорядок, достаточный для того, чтобы его было лень сортировать вручную.
Итак, запустим наш генератор хаоса через терминал.
python create_random_files.py
Поздравляю, теперь у нас полная папка неразберихи. Будем распутывать.
В той же директории, где create_random_files.py, создадим файл clean_up.py и поместим туда следующий код.
import os
import shutil
import glob
# перейти в папку RandomFiles
os.chdir('./RandomFiles')
# получить список файлов в папке RandomFiles
files_to_group = []
for random_file in os.listdir('.'):
files_to_group.append(random_file)
# получить все расширения имен всех файлов
file_extensions = []
for our_file in files_to_group:
file_extensions.append(os.path.splitext(our_file)[1])
print(set(file_extensions))
file_types = set(file_extensions)
for type in file_types:
new_directory = type.replace(".", " ")
os.mkdir(new_directory) # создать папку с именем данного расширения
for fname in glob.glob(f'*.{type[1:]}'):
shutil.move(fname, new_directory)
Для этого импортируем еще две библиотеки: shutil и glob. Первая поможет перемещать файлы, а вторая – находить и систематизировать. Но обо всем по порядку.
Для начала получим список всех файлов в директории.
Здесь мы предполагаем, что у нас нет ни малейшего понятия о том, какие именно файлы лежат в этой папке. Вместо того, чтобы вписывать все расширения вручную и использовать лестницу инструкций if или switch, мы желаем, чтобы программа сама просмотрела каталог и определила, на какие типы можно разделить его содержание. Что, если бы там были файлы с десятками расширений или логи? Вы бы стали описывать их вручную?
Получив список всех файлов, мы заходим в еще один цикл, чтобы извлечь расширения названий.
Обратите внимание на разделение строки:
os.path.splitext(our_file)[1]
Сейчас наша переменная our_file выглядит как-нибудь так: 5.docx. Когда разделим ее, получим следующее:
`('5', '.docx')` Мы возьмем отсюда второй элемент по индексу [1], то есть .docx. Ведь по индексу [0] у нас располагается 5.
Таким образом, у нас имеется список всех файловых расширений в папке, в том числе повторяющихся. Чтобы оставить только уникальные элементы, преобразуем его во множество. К примеру, если бы этот список состоял исключительно из .docx, повторяющегося снова и снова, то в set остался бы всего один элемент.
# создать множество и присвоить его переменной file_types = set(file_extensions)
Заметим, что в списке типов файлов каждое расширение содержит . в начале. Если мы назовем так папки на UNIX-системе, то они будут скрытыми, что не входит в наши намерения.
Поэтому, итерируя по нашему множеству, мы заменяем точку на пустую строку. И создаем папку с полученным названием.
new_directory = type.replace(".", " ")
# наша директория теперь будет называться "docx" Но чтобы переместить файлы, нам все еще нужно расширение .docx.
for fname in glob.glob(f'*.{type[1:]}') Этим попросту отбираем все файлы, оканчивающиеся расширением .docx. Заметьте, что в f'*.{type[1:]}') нет пробелов.
Символ подстановки * обозначает, что подходит любое имя, если оно заканчивается на .docx. Поскольку мы уже включили точку в поиск, мы используем [1:], что значит «все после первого символа». В нашем примере это docx.
Что дальше? Перемещаем любые файлы с данным расширением в директорию с тем же названием.
shutil.move(fname, new_directory)
Таким образом, как только в цикле создана папка для первого попавшегося файла с данным расширением, все последующие файлы будут отправлены в нее же. Все будет сгруппировано без повторения каталогов.
В качестве хитрого способа создать список в одну строку можно использовать генераторы.
import os
import shutil
import glob
# перейти в папаку RandomFiles
os.chdir('./RandomFiles')
# добавить все файлы в данной папке в список
all_files = [x for x in os.listdir('.')]
# создать множество расширений имен файлов в этой папке
file_types = set((os.path.splitext(f)[1] for f in all_files))
for ftype in file_types:
new_directory = ftype.replace(".", '')
os.mkdir(new_directory)
for fname in glob.glob(f'*.{ftype[1:]}'):
shutil.move(fname, new_directory)
Оба варианта сработают, и все ваши файлы будут отсортированы по расширению.
ManageFiles/
|
|_create_random_files.py
|_RandomFiles/
|_doc
|_docx
|_html
|_md
|_odt
|_ppt Вот и все. Если вам когда-либо понадобится отсортировать файлы таким образом, вы сэкономите немало времени ?. Код упражнения доступен здесь.
Если вы ищете работу на Python, на Talanto.work сейчас есть варианты для junior, middle, senior…
Рынок Python-вакансий большой, но удобным его назвать сложно. Формально вакансий много, однако в реальном поиске…
Срезы в Python — это больше, чем a[2:7]. В статье — быстрый разбор полезных приёмов:…
В этой статье мы рассмотрим возведение в степень в Python с помощью различных методов, от…
Дубликаты в списке Python — частая проблема. В статье показано, как быстро убрать повторы, в…
Услуга виртуального хостинга на SpaceWeb позволяет арендовать часть сервера (shared-сервера) и разместить на нём свой…