Я написал этот скрипт для поиска тома с достаточным количеством свободного места:
@echo on
setlocal
set gbsize=1,073,741,824
Set gbsize=%gbsize:,=%
for %%A in (A B C D) do (
for /f "tokens=3,4,5,*" %%B in ('dir %%A:\') do (
set bytesfree=%%B
set bytesfree=%bytesfree:,=%
if %%D == free If %bytesfree% gtr %gbsize% echo hi
)
)
Моя проблема в том, что переменная bytesfree не сохраняет свое значение. выход (эхо включено)
C:\Users\Desktop>(
set bytesfree=**780,607,488**
set bytesfree=**23167987712**
if free == free If 23167987712 GTR 1073741824 echo hi
)
hi
похоже, что bytesfree потерял свое значение. Кто-нибудь может помочь? и предоставить некоторые пояснения? Спасибо.
вместо просто setlocal, а затем используйте !bytesfree! для ссылки на переменную (просто замените % на !).
Более длинный ответ
Это связано с тем, что cmd расширяет переменные при анализе команды, а не при ее запуске (что, очевидно, происходит после анализа). команда в этом случае также может быть полным for оператором, включая блок после него. Таким образом, все экземпляры %bytesfree%внутри цикла заменяются их значением перед циклом, которое оказывается пустой строкой.
Отложенное расширение - это особая форма расширения переменных, которая расширяет переменные при запуске команды, а не при ее анализе. Его можно включить с помощью
setlocal enabledelayedexpansion
(в пакетном файле) или
cmd /v:on
(для всего сеанса, но не в пакетном файле, если вы не хотите, чтобы он возобновлялся).
Затем синтаксис !bytesfree! используется для ссылки на переменные, которые затем раскрываются непосредственно перед запуском команды. Таким образом, при настройке и использовании одной и той же переменной внутри блока (цикл for, if и т. д.) практически всегда требуется использовать отложенное раскрытие.
Ответ 2 · рейтинг 4 · dbenham
Чтобы расширить ответ Джоуи (исходный короткий), все выражение for анализируется сразу, а расширение% происходит во время анализа. Но нужного вам значения нет, пока не будет выполнено предложение DO. Вот почему вам нужно отсроченное расширение. Прочтите справку по for, набрав HELP FOR в командной строке.
Основываясь на комментарии к вашему предыдущему вопросу https://stackoverflow.com/a/9096601/1012053, похоже, что вы пытаются найти диск с наибольшим объемом свободного места > 1 ГБ.
Ваш текущий код имеет небольшой риск включения неправильной строки из команды DIR. Я изменил его для фильтрации вывода с помощью FINDSTR с регулярным выражением.
EDIT. Кроме того, команда IF не может корректно сравнивать числа, превышающие 2 147 483 647.
Таким образом, числа должны иметь префикс 0, а команда IF должна выполнять сравнение строк вместо числового сравнения. Я заставил сравнение строк, заключив число с префиксом 0 в кавычки.
@echo off
setlocal enableDelayedExpansion
set "gbsize=1,073,741,824"
set "gbsize=%gbsize:,=%"
set "maxfree=000000000000000"
set "maxdrive="
for %%A in (C D) do (
for /f "tokens=3" %%B in ('dir %%A:\^|findstr /r /c:"^ *.* *Dir(s).*bytes free$"') do (
set "bytesfree=000000000000000%%B"
set "bytesfree=!bytesfree:,=!"
set "bytesfree=!bytesfree:~-15!"
if "!bytesfree!" gtr "!maxfree!" (
set "maxfree=!bytesfree!"
set "maxdrive=%%A:"
)
)
)
for /f "tokens=* delims=0" %%A in ("%maxfree%") do set maxfree=%%A
echo Drive with max free space is %maxdrive% %maxfree% bytes free
if %maxfree% gtr %gbsize% echo That is more than 1GB
Альтернативный метод с использованием WMIC
@echo off
setlocal enableDelayedExpansion
set "gbsize=1,073,741,824"
set "gbsize=%gbsize:,=%"
set "maxfree=000000000000000"
set "maxdrive="
for /f "skip=1 tokens=1,2" %%A in ('wmic volume get DriveLetter^, FreeSpace') do (
if "%%B" neq "" (
set "bytesfree=000000000000000%%B"
set "bytesfree=!bytesfree:~-15!"
if "!bytesfree!" gtr "!maxfree!" (
set "maxfree=!bytesfree!"
set "maxdrive=%%A"
)
)
)
for /f "tokens=* delims=0" %%A in ("%maxfree%") do set maxfree=%%A
echo Drive with max free space is %maxdrive% %maxfree% bytes free
if %maxfree% gtr %gbsize% echo That is more than 1GB