Сохранить значения командного файла
Я написал этот скрипт для поиска тома с достаточным количеством свободного места:
@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 потерял свою ценность. Может кто-нибудь, пожалуйста, помогите? и дать некоторые объяснения? Благодарю.
2 ответа
Короткий ответ:
использование
setlocal enabledelayedexpansion
вместо просто setlocal
а затем использовать !bytesfree!
ссылаться на переменную (просто заменить %
от !
).
Более длинный ответ:
Это потому что cmd
расширяет переменные при анализе команды, а не при ее выполнении (что, очевидно, происходит после анализа). Команда в этом случае также может быть полной for
заявление, включая блок после него. Так что все случаи %bytesfree%
в цикле заменяются их значения перед циклом, который оказывается пустой строкой.
Отсроченное расширение - это особая форма расширения переменных, которая расширяет переменные при выполнении команды, а не при ее анализе. Это может быть включено с
setlocal enabledelayedexpansion
(в пакетном файле) или
cmd /v:on
(для полного сеанса, но не в пакетном файле, если вы не хотите, чтобы он возобновлялся).
Тогда синтаксис !bytesfree!
используется для ссылки на переменные, которые затем раскрываются непосредственно перед выполнением команды. Таким образом, при установке и использовании одной и той же переменной в блоке (for
петли, if
и т. д.) Вы почти всегда хотите использовать отложенное расширение.
Чтобы развернуть ответ Джоуи (оригинальный короткий), все выражения for анализируются сразу, а расширение% происходит во время анализа. Но нужного вам значения нет, пока не выполнится предложение DO. Вот почему вам нужно отсроченное расширение. Прочтите справку по, набрав HELP FOR из командной строки.
Исходя из комментария к вашему предыдущему вопросу /questions/1272172/paketnyie-fajlyi-sravnivayut-chisla/1272178#1272178, похоже, что вы пытаетесь найти диск с наибольшим количеством свободного места> 1 ГБ.
Ваш текущий код имеет небольшой риск включения неправильной строки из команды DIR. Я изменил его, чтобы отфильтровать вывод, используя FINDSTR с регулярным выражением.
РЕДАКТИРОВАТЬ - Кроме того, команда IF не может правильно сравнить числа, которые превышают 2147483647.
>if 2147483647 gtr 2147483646 echo greater
greater
>if 2147483648 gtr 2147483647 echo greater
>if 1000000000000 gtr 2147483647 echo greater
>if 2147483648 equ 2147483647 echo equal
equal
>if 1000000000000 equ 2147483647 echo equal
equal
Таким образом, числа должны иметь префикс 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