Как это будет лучше реализовать, можно ли оптимизировать алгоритм?
Лучше написать несколько разных скриптов. Один скрипт должен принимать каталог и с ним проделывать свои действия. А потом пишется скрипт, который соединяет эти независимые скрипты в одну систему.
1. Найти все jpg в выбранной папке.
Ну, вот один скрипт находит все jpg файлы в заданной папке и переносит их в новую папку, которая предназначена для дальнейшей обработки (какой обработки - он не знает и не должен знать).
Скрипт принимает имя папки, искомое расширение файлов и имя новой папки для сохранения.
2. Для каждого jpg проверить заголовки (могу ошибаться, но они вроде есть в jpg) на целостность (мало ли файл повреждён или файл не является фотографией, а просто файлом с расширением jpg).
Второй скрипт так же принимает папку и проверяет в ней файлы на целостность. Результат его работы какой? Например, перенос нецелых файлов в новую папку. Дальше он тоже не знает, что там будет делаться с целыми или нецелыми файлами.
Скрипт принимает имя папки, искомое расширение файлов и имя новой папки для сохранения.
3.Информацию о каждом файле (имя и относительный путь, хэш, exif-тэги) записать в csv файл (или что-то подобное).
Третий скрипт принимает папку и пишет информацию о файлах в ней в csv-файл.
Скрипт принимает имя папки, искомое расширение файлов и имя файла для сохранения.
4.Найти дубликаты и применить фильтры (допустим - должны быть все exif тэги).
Четвёртый скрипт принимает папку, ищет дубликаты и удаляет их.
Пятый скрипт принимает папку и применяет фильтры к файлам в ней.
(Надеюсь, ты понял, что их нельзя объединять в один скрипт.)
5.Скопировать/переместить оставшиеся файлы в заданную структуру папок.
Шестой скрипт принимает папку и перемещает файлы из неё в структуру папок.
Скрипт принимает имя папки и имя новой папки для сохранения.
Вот, и в конце ты пишешь седьмой скрипт, управляющий этими скриптами, который знает, куда и какую папку подавать на каждом этапе.