1

В настоящее время я пытаюсь сделать некоторые пакетные слияния и переименование, и я перед следующей проблемой (это не фактический код, а скорее MWE демонстрирует проблему):Batch - набор переменных в цикле

@echo off 
set /p "arg=Input the path to target directory (defaults to current directory if left empty): " 

for %%f in ("%arg%\*.mkv") do (
    echo %%~nf 
    set "out=%%~nf" 
    echo %out% 
) 

pause 

Моя проблема заключается в том, что эти два эха не печатают одинаковые значения. Первая печатает правильную вещь (имя файла), вторая печатает что-то случайное, например Echo is OFF или последнее имя файла каталога.

После небольшого поиска я нашел упоминание об использовании замедленного расширения переменных (setlocal EnableDelayedExpansion), но это вызывает проблему, поскольку путь к каталогу вход пользователя может содержать восклицательные знаки, которые удаляются, если я это делаю (и поэтому цикл for не выполняется вообще).

Как правильно настроить переменные в цикле for?

UPDATE

С помощью решения Денниса и некоторых дополнительных проб и ошибок, я, наконец, смог исправить исходный код, и теперь он работает. Для тех, кто заинтересован, это то, что я пытался сделать:

for %%f in ("%arg%\*.mkv") do (
    set "n=%%~nf" 

    setlocal EnableDelayedExpansion 
    mkvmerge -o "!n:~15,10! !n:~25!" "!n!_Track00.h264" ... 
    endlocal 
) 

Фактическая команда на самом деле гораздо больше, так что я не вставляя его в полном объеме, просто вставив достаточно, чтобы продемонстрировать, что требуется в нем как аргументы. Я использовал переменную n, потому что %% ~ nf плохо функционирует внутри среды с задержкой расширения (т. Е. Удаляется), и я не знаю, как разыменовать двухпроцентные переменные (параметры?) С задержкой расширения.

Кроме того, попытки

set "out=%n:~15,10% %n:~25%" 

перед установкой замедленного расширения, а затем работает

mkvmerge -o "!out!" ... 

не замедлили расширение должным образом, приведенный выше код было то, что я закончил с.

+0

Вы должны использовать! вместо% внутри цикла for, поэтому 'echo! out!'. Предлагаю посмотреть [здесь] (http://ss64.com/nt/delayedexpansion.html) –

+0

включить delayedexpansion ** и ** использовать! внутри цикла. –

+1

Возможный дубликат [Переменные пакетного файла, инициализированные в цикле for] (https://stackoverflow.com/questions/691047/batch-file-variables-initialized-in-a-for-loop) –

ответ

3

Вы должны попробовать это:

@echo off 
set "arg=." 
set /p "arg=Input the path to target directory (defaults to current directory if left empty): " 
for %%f in ("%arg%\*.mkv") do (
    echo %%~nf 
    set "out=%%~nf" 
    setlocal EnableDelayedExpansion 
    echo !out! 
    endlocal 
) 
pause 
+0

Я обновил вопрос , Это дает мне ошибку на глубине рекурсии setlocal. –

+0

Отредактировано, вам нужен endlocal not setlocal disable –

+0

ОК, это работает лучше, но все еще имеет проблему, так как по-прежнему удаляет восклицательные знаки в именах файлов (они также могут включать в себя! S). Есть ли способ избежать удаления меток в именах? –

Смежные вопросы