我编写了这个脚本来寻找具有足够可用空间的卷:
@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变量dosent保存其值。输出是(回声打开)
C:\Users\Desktop>(
set bytesfree=**780,607,488**
set bytesfree=**23167987712**
if free == free If 23167987712 GTR 1073741824 echo hi
)
hi
看起来像bytesfree失去了它的值。 有人可以帮忙吗?并提供一些解释? 感谢。
答案 0 :(得分:4)
要扩展Joey(原始简短)的答案,将立即解析整个for表达式,并在解析时发生%扩展。但是在DO子句执行之前,你想要的值就不存在了。这就是你需要延迟扩张的原因。通过从命令行键入HELP FOR来阅读有关的帮助。
根据您之前提问https://stackoverflow.com/a/9096601/1012053的评论,您似乎正在尝试查找具有最多可用空间的驱动器> 1GB。
您当前的代码存在从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
答案 1 :(得分:2)
使用
setlocal enabledelayedexpansion
而不只是setlocal
,然后使用!bytesfree!
来引用变量(只需将%
替换为!
)。
这是因为cmd
扩展变量,因为它解析一个命令,而不是在运行命令时(显然在解析之后发生)。在这种情况下,命令也可以是完整的for
语句,包括之后的块。因此,循环中<{1}} 的所有实例都会在循环之前被它们的值替换,这恰好是一个空字符串。
延迟扩展是一种特殊形式的变量扩展,它在运行命令时扩展变量,而不是在解析时扩展变量。可以使用
启用它%bytesfree%
(在批处理文件中)或
setlocal enabledelayedexpansion
(对于完整的会话,但不在批处理文件中,除非您不希望它恢复)。
然后语法cmd /v:on
用于引用在运行命令之前扩展的变量。因此,当在块(!bytesfree!
循环,for
等)中使用相同的变量设置和时,您几乎总是希望使用延迟扩展