Можно сделать обобщённое решение. Описываешь функцию преобразования, которая имя файла превращает в относительный путь к файлу.
from os import path
def get_folder(fname: str) -> str:
... # тут будет код
base_folder = r'C:\тут\корневой\каталог\куда\складывать\файлы'
for file in files: #перебираешь список файлов, у тебя этот код уже есть
subpath = get_folder(path.basename(file))
if subpath is None: # если функция вернула None, игнорируем файл
continue
source_path = path.abspath(file)
target_path = path.join(base_folder, subpath)
# и переносишь/копируешь файл из source_path в target_path
Хорошо, а как реализовать get_folder()?
Описываешь имя файла регуляркой, например, такого вида:
\w+?(?P<Num>\d+)\.(?P<Ext>\w+)
Как видим, эта регулярка содержит две именованных захватываемых группы - цифры перед точкой Num, и расширение Ext.
Если тебе хватит точного совпадения, и не требуется делать что-то вида "файлы с цифрами 000-100 в папку 100", то реализация будет примерно такая:
import re
NAME = re.compile(r'\w+?(?P<Num>\d+)\.(?P<Ext>\w+)', re.I)
TYPES = { #сортировка по типам
'aac': 'AUDIO',
'mp4': 'VIDEO',
'jpg': 'IMAGES',
None: 'MISC', #всё остальное
}
def get_folder(fname: str) -> str:
m = NAME.match(fname) #пусть имя файла anything100.jpg
if m is None: #имя файла не по шаблону - непонятно что делать с файлом
return None # или говорим "не трогай файл"
#return f'{TYPES[None]}/{fname}' # или кидаем в папку для неразобранного
data = m.groupdict() # data = { 'Num': '100', 'Ext': 'jpg' }
data['File'] = fname # data = { 'Num': '100', 'Ext': 'jpg', 'File': 'anything100.jpg' }
data['Type'] = TYPES.get(data['Ext'].lower(), TYPES[None]) # data = { 'Num': '100', 'Ext': 'jpg', 'File': 'anything100.jpg' , 'Type': 'IMAGES' }
return '{Type}/{Type}{Num}/{File}'.format(**data) # IMAGES/IMAGES100/anything100.jpg
Дальше подгонишь как тебе надо, меняя реализацию get_folder().