Ответ 1
В блочном выражении (a parenthesised series of statements)
выполняется синтаксический анализ целого и , затем. Любой %var%
внутри блока будет заменен значением переменной в момент анализа блока - до того, как будет выполнен блок - то же самое относится к FOR ... DO (block)
.
Следовательно, IF (something) else (somethingelse)
будет выполняться с использованием значений %variables%
во время возникновения IF
.
Два общих способа преодоления этого: 1) использовать setlocal enabledelayedexpansion
и использовать !var!
вместо %var%
для доступа к измененному значению var
или 2) для вызова подпрограммы для дальнейшей обработки с использованием измененные значения.
Обратите внимание, что использование CALL ECHO %%var%%
, которое отображает измененное значение var
.
Ваш код содержит две отдельные переменные, называемые f
.
Первый - это метастабильный цикл, называемый f
и ссылающийся на %%f
.
Вторая - это общая переменная среды f
, которая устанавливается оператором set "f=..."
. Доступ к этой переменной можно получить с помощью %f%
, но в block
, он сохранит значение, которое было у него при анализе контрольного for
(фактически, любой %var%
заменен во время разбора на значение var
в это время)
metavariables
не может использоваться в операторах строковой манипуляции, таких как подстроки или заменители, для этих операций могут использоваться только общие переменные среды, поэтому вам необходимо присвоить значение метаобменимой f
переменной окружения f
а затем выполнить задачу замены строки переменной окружения f
.
Конечно, вы должны использовать синтаксис delayedexpansion
и !var!
для доступа к модифицированному значению переменной среды внутри блока.
Итак,
setlocal enabledelayedexpansion
for...%%f...do (
echo %%f
set "f=%%f"
set "f=!f:\=/!"
echo !f!
)
echo just for demonstration %f% !f! %%f
Это устанавливает значение f
необходимым образом (конечно, вы всегда можете изменить имя, чтобы избежать путаницы...)
Последняя строка - это просто показать, что конечное значение, полученное с помощью f
, можно получить за пределами цикла как либо %f%
, либо !f!
, а %%f
- вне контекста и показано как %f
.
Другой способ сделать это без delayedexpansion
-
for...%%f...do (
echo %%f
set "f=%%f"
call set "f=%%f:\=/%%"
call echo %%f%%
)
echo just for demonstration %f% !f! %%f
разница заключается в использовании call
и удвоении %
s, а в финальной строке будет отображаться !f!
как раз это - литерал, поскольку вне режима delayedexpansion
!
- это просто другое символ, не имеющий особого значения для cmd
.