Введение
У вас десятки тысяч JPG-фото, разбросанных по подпапкам, и многие файлы не имеют ключевых слов (keywords) в метаданных. Нужно просканировать всю структуру папок и скопировать или переместить все JPG, у которых отсутствуют ключевые слова, в дубликат той же структуры папок.
Ниже — простое, рабочее решение на основе ExifTool и командной строки Windows, разъяснение параметров и пример вывода. Все шаги проверены на примере, сохранены важные факты и примеры команд.
Задача
Найти и скопировать/переместить все JPG-файлы, у которых в метаданных нет Keywords (или Subject). Сохранить исходную структуру папок в результирующей директории. Рабочая система: Windows 10, установлен ExifTool, опыт с Batch scripting приветствуется.
Решение одной командой с ExifTool
ExifTool обладает встроенными возможностями пакетной обработки, поэтому для этой задачи обычно достаточно одной команды. Важно: сначала перейдите (CD) в корневую папку дерева, которое хотите сохранить (например, F:\testFindNoKeywords). Выполняйте команду в Windows CMD (не в PowerShell). На Mac/Linux замените двойные кавычки одинарными.
Пример команды для Windows CMD:
exiftool -r -if "not $keywords and not $subject" "-Directory=F:\testFindNoKeywordsResult\%d" .
Если хотите перемещать вместо копирования, ExifTool по умолчанию обновляет Directory, что фактически перемещает/копирует файл в указанную директорию с сохранением подкаталогов благодаря переменной %d.
Разбор команды и ключевые параметры
-r (или -recurse). Эта опция рекурсивно обходит все подпапки, позволяя обработать десятки тысяч JPG-файлов в дереве каталогов. Без -r ExifTool обработает только файлы в текущей директории.
-if «not $keywords and not $subject». Параметр -if принимает Perl-выражение, которое проверяется для каждого файла. В данном случае условие истинно только для файлов, у которых нет полей Keywords и Subject в метаданных (XMP / IPTC).
-Directory=»F:\testFindNoKeywordsResult\%d». Параметр -Directory указывает место назначения. %d подставляется как путь к директории файла относительно каталога, из которого вы запускали команду. Поэтому нужно сначала CD в корень обрабатываемого дерева, чтобы относительные пути создавались корректно.
. (точка). Точка в конце означает текущую директорию — корень дерева, откуда начнётся рекурсивный поиск.
Пример: структура файлов и результат
Исходная структура (пример):
Y:\!TEMP\X\Y\A
│ 1.jpg
│
└───b
│ 2.jpg
│
└───c
3.jpg
Проверка метаданных:
exiftool -G1 -a -s -Keywords -Subject -r .\a
======== ./a/1.jpg
[XMP-dc] Subject : 1
======== ./a/b/2.jpg
[IPTC] Keywords : 2
======== ./a/b/c/3.jpg
3 directories scanned
3 image files read
Команда для поиска файлов без keywords/subject и помещения их в новую папку:
exiftool -r -if "not $keywords and not $subject" "-Directory=Y:\!temp\x\y\NoKeywordsFound\%d" .\a
3 directories scanned
1 directories created
2 files failed condition
1 image files updated
0 image files read
Результат — скопированное/перемещённое дерево с найденными файлами:
Y:\!TEMP\X\Y\NoKeywordsFound
└───a
└───b
└───c
3.jpg
В примере файлы 1.jpg и 2.jpg содержали ключевые слова (Subject или Keywords), а 3.jpg — нет, поэтому именно он оказался в папке NoKeywordsFound.
Важно: не вызывать ExifTool в цикле для каждого файла
Не рекомендуется запускать ExifTool в цикле (по одному файлу за запуск). Самая большая потеря времени — время запуска ExifTool, и при 10 000+ файлах многократный старт значительно замедлит процесс. Используйте встроенную рекурсию и условие -if для пакетной обработки (это описано как распространённая ошибка — «Over-scripting»).
Альтернативный batch-скрипт (пример)
Ниже приведён пример batch-файла, который делает аналогичную задачу: копирует файлы без XMP/IPTC в указанную папку, воспроизводя структуру. Тестируйте на тестовых файлах — в некоторых случаях JPG могут не содержать XMP или IPTC, и скрипт может выбрать больше файлов, чем ожидается.
Пример batch:
@echo off
chcp 1252 >nul
set "Source=%userprofile%\desktop\test\source"
set "Destiny=%userprofile%\desktop\test\destiny"
if not exist "%Source%" exit
if not exist "%Destiny%" md "%Destiny%"
For /f "delims=" %%a in ('exiftool -p "$directory\$filename" -api filter^="tr(/)(\\)" -s3 -q -if "not $xmp:all and not $iptc:all" -r "%Source%\*.jpg"') do (
if not exist "%Destiny%%%~pa" md "%Destiny%%%~pa"
copy "%%~a" "%Destiny%%%~pa"
)
Замечание по совместимости и тестированию
Команды выше предназначены для Windows CMD. На Mac/Linux используйте одинарные кавычки в -if и в других местах по необходимости. Обязательно протестируйте команды и скрипты на небольшой тестовой выборке перед запуском на десятках тысяч JPG-файлов.
Ключевые слова и термины, используемые в статье: ExifTool, JPG, keywords, metadata, Windows 10, Batch scripting, XMP, IPTC, -r, -if, -Directory, %d.