Это пример того, как разделить имя файла на первый символ дефиса.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /R %%A in (*.mkv *.avi *.mp4) do (
for /F "eol=| tokens=1* delims=-" %%B in ("%%~nA") do (
set "Artist=%%B"
set "Title=%%C"
setlocal EnableDelayedExpansion
if "!Artist:~-1!" == " " set "Artist=!Artist:~0,-1!"
if defined Title if "!Title:~0,1!" == " " set "Title=!Title:~1!"
echo Artist=!Artist!
if defined Title (echo Title=!Title!) else echo %%~na has no title.
endlocal
)
)
endlocal
Внешний цикл FOR ищет рекурсивный поиск в текущем каталоге и во всех подкаталогах для скрытогофайлы с расширением mkv
, avi
или mp4
и присваивает полное имя файла (путь к файлу + имя файла + расширение файла) найденного файла переменной цикла A
.
Внутренний цикл FOR интерпретирует только имя файла без пути и расширение файла как строку для обработки.
Символ конца строки переопределяется по умолчанию ;
, который может находиться в начале файлаимя |
, которое никогда не может содержать имя файла, чтобы избежать случайного имени файла, начинающегося с точки с запятой, внутренним циклом FOR .
По умолчанию FOR с опцией /F
обработка строки в двойных кавычках разбивает строку на подстроки с использованием обычного пробела и горизонтальной табуляции в качестве разделителей строк и назначает только первый пробел / разделитель табуляцииНоминальная строка для указанной переменной цикла.Это поведение разделения строк изменяется с помощью tokens=1* delims=-
для разделения строки имени файла на дефисы вместо пробелов / табуляций с игнорированием дефисов в начале имени файла и назначением строки до первого дефиса внутри имени файла для указанной переменной цикла B
и все после первого (последовательности) дефиса (ов) до следующей переменной цикла в соответствии с ASCII таблицей без дальнейшего разделения строки, которое является переменной цикла C
.
Другими словами наимя файла, например Artist - title
, строка Artist
с пробелом в конце присваивается переменной цикла B
, а строка title
с пробелом в начале присваивается переменной цикла C
.Два нежелательных пространства должны быть удалены.Это можно сделать с помощью подстановки строк.Но это должно быть сделано с использованием отложенное расширение , которое еще не включено, поскольку имена файлов, содержащие восклицательный знак, также должны обрабатываться правильно.По этой причине отложенное расширение переменной среды затем включается во внутреннем цикле FOR .
Первое условие IF проверяет, является ли последний символ строки Artist действительно пробеломи выполняет подстановку строки для удаления этого пробела в конце строки исполнителя, если это условие истинно.
Второе условие IF сначала проверяет, определена ли переменная среды Title
, потому что она вообще определена, потому чтокоманд внутреннего цикла FOR также выполняются для имени файла, вообще не содержит дефис, в этом случае %%C
раскрывается в пустую строку, поэтому переменная окружения Title
удаляется из списка окруженияпеременные.
Вложенное третье условие IF проверяет, является ли первый символ значения определенной переменной среды Title
пробелом, и выполняет подстановку строки, чтобы переопределить Title
без первого символа, если этоусловие истинно.
Теперь строки артиста и заголовка могут быть выведены перед delрасширение ayed снова отключается путем восстановления предыдущей среды.Пожалуйста, прочитайте этот ответ для подробностей о командах SETLOCAL и ENDLOCAL и что именно происходит при каждом выполнении SETLOCAL и ENDLOCAL из-за гораздо большего, чем просто включение и отключение отложенного расширения переменной среды для каждого найденного имени файла.
Примечание: Часть заголовка может содержать также пространство последовательности символов,дефис, пробел, а также один или несколько дефисов, но, конечно, строка исполнителя не должна содержать дефис, поскольку этот символ интерпретируется как разделитель между исполнителем и названием независимо от пробелов, существующих вокруг дефиса или нет.Процессор команды Windows не предназначен для расширенных манипуляций со строками, как другие интерпретаторы сценариев.Другой код будет необходим, если условием для разделения имени файла по исполнителю и заголовку должны быть пробел, дефис, пробел, а не просто дефис.
Другой код пакетного файла, использующий -
для разделения имени файла на строки исполнителя и заголовка:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /R %%A in (*.mkv *.avi *.mp4) do call :ProcessFileName "%%~nA"
endlocal
goto :EOF
:ProcessFileName
set "FileName=%~1"
set "Title=%FileName:* - =%"
setlocal EnableDelayedExpansion
set "Artist=!FileName: - %Title%=!"
echo Artist=!Artist!
echo Title=!Title!
endlocal
goto :EOF
Но это решение, использующее только подстановки строк в подпрограмме, не работает с строкой заголовка, содержащей знак равенстваиспользуется в качестве разделителя при подстановке строк.Это также намного медленнее по сравнению с вышеупомянутым решением для пакетных файлов при обработке большого количества имен файлов.
Для понимания используемых команд и их работы откройте окно командной строки, выполните там следующие команды иочень внимательно прочитайте все справочные страницы, отображаемые для каждой команды.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?
См. Также Куда возвращается GOTO: EOF?