Вам нужно использовать отложенное расширение:
setlocal enabledelayedexpansion
for /f "tokens=*" %%M in ('dir * /b') do (
set files=!files! %%M
)
echo END %files%
Документацию по этому вопросу вы можете найти в help set
:
Задержка расширения переменной среды полезна для обхода
ограничения текущего расширения, которое происходит, когда линия
текста читается, а не когда он выполняется. Следующий пример
демонстрирует проблему с немедленным расширением переменной:
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo If you see this, it worked
)
никогда не будет отображать сообщение, так как %VAR%
в обоих операторах IF
подставляется при чтении первого оператора IF
, поскольку он логически
включает тело IF
, которое является составным оператором. Итак
IF
внутри составного оператора действительно сравнивает «до» с
«после», которое никогда не будет равным. Аналогично, следующий пример
не будет работать должным образом:
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
в том смысле, что не создаст список файлов в текущем каталоге,
но вместо этого для переменной LIST
будет установлен последний найденный файл.
Опять же, это потому, что %LIST%
раскрывается только один раз, когда
Оператор FOR
читается, и в это время переменная LIST
пуста.
Итак, фактический цикл FOR
, который мы выполняем:
for %i in (*) do set LIST= %i
, который просто устанавливает LIST
на последний найденный файл.
Кроме того, вы никогда не должны использовать for /f
для итерации по выводу dir
, поскольку это может быть неуловимым. Вам нужна специальная обработка для имен файлов с пробелами, и это разрывается с растровыми шрифтами и Unicode. По сути, вы говорите: «Привет, я запускаю команду, токенизирую ее вывод, преобразованный в текущую кодовую страницу OEM, и пытаюсь работать с этим, вместо того, чтобы просто попросить for
перебрать файлы»:
for %%M in (*) do ...