переименовать файлы с определенными символами с помощью cmd - PullRequest
0 голосов
/ 23 ноября 2018

Я не нашел других сообщений об этой конкретной необходимости.Пример:

Наруто NA - 480p.mp4

Я хочу стереть «NA», чтобы оно было

Наруто - 480p.mp4

Я пробовал с

for /f "tokens=1*delims=NA" %%a in ('dir /b "*NA*.*"') do ren "%%aNA%%b" "%%a%%~xb"

, но вывод

Наруто .mp4

не только«- 480p» больше нет, но между Наруто и .mp4

есть пробел

1 Ответ

0 голосов
/ 24 ноября 2018

Возможны несколько решений.

Первое работает, пока имя файла не содержит одно или несколько !:

@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:

  1. Первая подстрока (токен) Naruto должна быть назначена указанной переменной цикла A.
  2. Вторая подстрока NA должна быть назначена следующей переменной цикла B в соответствии с ASCII таблицей .
  3. И остальной частью строки после всех пробелов после второгоРазделенная пробелами подстрока должна быть назначена следующей, но одной переменной цикла 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 /?
...