批处理:处理 2^32 以上的数字

Batch: Handle numbers above 2^32

我想在依赖于我的可用存储 space 的批处理文件中执行操作,但它失败了(有趣的是,只是有时),因为可用 space 超过 2GB,使得变量不可设置。

这是批处理文件:

cd "C:\Users\Fabian\Desktop\Screen Recordings\Auto"
for /F "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace /format:value`) do (set FreeSpace=%%x)
if (%FreeSpace%) LSS (2499522027520) (
for /F "delims=" %%a in ('dir /b /a-d /t:w /o:d "C:\Users\Fabian\Desktop\Screen Recordings\Auto\*.flv"') do (
del "%%a"
goto :breakLoop
))
:breakLoop
exit

其中很多只是 Windows 怪异现象的解决方法,重要的部分是:set FreeSpace=%%x
x 是直接从活动磁盘数据中提取的字符串,应该转换为数字,但由于它大于 232,因此失败(并且它使一个字符串,使下一行的比较成为字符串比较,这根本不是我想要的)。
我也不能将它除以一个数字,因为那将要求它首先是一个数字。

我是否必须通过更改字符串的长度来使用在末尾截断数字的粗略技巧(如果是,如何?)或者是否有适当的方法 long批处理文件中的数字?

我发现 this script (archive) 实际上有效,但我不知道如何。它的哪一部分砍掉了数字,哪一部分是我需要的重要部分?我不能让它每次都汇总所有文件夹大小,因为脚本每 20 秒运行一次。

在 Windows 命令提示符下无法处理超出 -231 = -2147483648 到 32 位有符号整数范围的数字231 - 1 = 2147483647.

然而,您可以使用 sub-string expansion 删除几个数字,比如 6,在右边有一个四舍五入的兆字节数而不是字节数,并将结果用于数字比较,比如这个:

cd "%USERPROFILE%\Desktop\Screen Recordings\Auto"
set "FreeSpace=0"
for /F "usebackq skip=1" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace^,Size`) do (set "FreeSpace=%%x")

rem // Remove the last 6 digits to get MBytes:
set "FreeSpaceMB=%FreeSpace:~,-6%"
rem // Ensure to not leave an empty value behind:
if not defined FreeSpaceMB set "FreeSpaceMB=0"

if %FreeSpaceMB% LSS 2499522 (
    for /F "delims=" %%a in ('dir /B /A:-D /T:W /O:D "C:\Users\Fabian\Desktop\Screen Recordings\Auto\*.flv"') do (
        del "%%a"
        goto :breakLoop
    )
)
:breakLoop
exit /B

当然你会失去精度,但这对于手头的目的来说可能是可以接受的。

我还更改了捕获 wmic 输出的 for /F 循环,以避免 Unicode 转换伪像,如孤立的回车 -return (CR) 字符,这会导致变量 FreeSpace 包含一个数字加上一个 CR。这就是为什么我也查询了值 Size 虽然不需要它,但是 FreeSpace 值不是最后一个可能被 CR 尾随的值。

顺便说一句,请注意我从 if 命令行中删除了多余的括号。