Возможны несколько решений.
Первое работает, пока имя файла не содержит одно или несколько !
:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for %%I in ("* NA -*") do (
set "FileName=%%~nI"
ren "%%I" "!FileName:NA -=-!%%~xI"
)
endlocal
Имя файла текущего файла назначенобез расширения файла до переменной среды FileName
.Перед выполнением команды REN командный процессор Windows выполняет подстановку строк, чтобы заменить регистронезависимые все вхождения NA -
просто -
в имени файла, чтобы удалить ненужную часть имени файла.
Проблема заключается в строке set "FileName=%%~nI"
, в результате которой имя файла, на которое ссылается %%~nI
, содержит один или несколько восклицательных знаков, что командный процессор Windows снова анализирует эту командную строку после замены %%~nI
на имя файла текущегофайл и интерпретирует каждый !
как начало / конец переменной среды, на которую ссылается задержка.
Второе решение работает также для имен файлов с восклицательными знаками:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%I in ("* NA -*") do (
set "FileName=%%~nI"
setlocal EnableDelayedExpansion
ren "%%I" "!FileName:NA -=-!%%~xI"
endlocal
)
endlocal
Назначение имени файлатекущего файла в переменную окружения FileName
выполняется, когда отложенное расширение переменной окружения отключено, поэтому !
интерпретируется как буквенный символЗатем отложенное расширение включается, чтобы иметь возможность использовать подстановку строк перед переименованием файла и восстановлением предыдущей локальной среды.
Еще одно решение для переименования Naruto NA - 480p.mp4
в Naruto - 480p.mp4
- это:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir "* NA -*" /A-D-H /B 2^>nul') do for /F "eol=| tokens=1,2* delims= " %%A in ("%%~nxI") do ren "%%I" "%%A %%C"
endlocal
Внешний FOR с опцией /F
и строка в круглых скобках, заключенная в одинарные кавычки, запускается в отдельном командном процессе, начинающемся с cmd.exe /C
в фоновом режиме командной строки:
dir "* NA -*" /A-D-H /B 2>nul
DIR ищет в текущем каталоге
- не скрытых файлов из-за опции
/A-D-H
(атрибут не каталог и не скрытый) - в соответствии с шаблоном подстановки
* NA -*
и - выводят построчно в формате для обработки STDOUT только имена файлов с расширением файла без пути из-за опции
/B
.
DIR также может выдать сообщение об ошибке для обработки STDERR в случае, если не найден скрытый файл, соответствующий шаблону подстановочного знака.Это сообщение об ошибке перенаправляется с помощью 2>nul
на устройство NUL для его подавления.
Прочтите статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul
,Оператор перенаправления >
должен быть экранирован с помощью символа вставки ^
в FOR командной строке, чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку dir
в отдельном командном процессе, запущенном в фоновом режиме.
FOR захватывает все выходные строки для обработки STDOUT запущенного командного процесса и обрабатывает ихстроки после запуска cmd.exe
завершены.
Пустые строки игнорируются FOR , которые здесь не встречаются.
Строки, начинающиеся с ;
, также игнорируются FOR из-за значения по умолчанию для конца строки.Имя файла может начинаться с точки с запятой.По этой причине eol=|
используется для определения вертикальной черты как символа конца строки, который не может содержать имя файла.
FOR разделит строку на подстроки с использованием обычного пробела и горизонталиtab как разделители строк и назначит только первую строку с пробелом / символом табуляции для указанной переменной цикла I
.Такое поведение здесь нежелательно, поскольку имена файлов содержат несколько пробелов.Поэтому delims=
используется для определения пустого списка разделителей, чтобы отключить это поведение разделения строки команды FOR .
Текущее имя файла, назначенное с использованными параметрами полностью указанной переменной циклаI
даже при запуске с ;
или с одним или несколькими пробелами обрабатывается как строка внутренним FOR .
eol=|
снова используется для внутреннего FOR , чтобы избежать игнорирования имени файла, начинающегося с ;
.Для внутреннего FOR желательно разделение строки имени файла на пробелы, поэтому опция delims=
используется для явного определения только пробела в качестве разделителя.Строка имени файла должна быть разбита на все вхождения одного или нескольких пробелов на три части для Naruto NA - 480p.mp4
:
- Первая подстрока (токен)
Naruto
должна быть назначена указанной переменной цикла A
. - Вторая подстрока
NA
должна быть назначена следующей переменной цикла B
в соответствии с ASCII таблицей . - И остальной частью строки после всех пробелов после второгоРазделенная пробелами подстрока должна быть назначена следующей, но одной переменной цикла
C
, которая для этого примера - 480p.mp4
.
Это может быть достигнуто с помощью опции tokens=1,2*
.
Вкл.команда REN вторая подстрока опущена, поэтому новое имя файла Naruto - 480p.mp4
.
Конечно, это третье решение не работает, например, для файла с именем Naruto Uzumaki NA - 480p.mp4
, потому что newимя будет Naruto NA - 480p.mp4
, так как в этом случае подстрока с разделителями из второго пробела будет Uzumaki
, а не NA
.
Для понимания используемых команд и их работы откройте окно командной строки, выполните командувыполните следующие команды и полностью прочитайте все справочные страницы, отображаемые для каждой команды.
dir /?
echo /?
endlocal /?
for /?
ren /?
set /?
setlocal /?