青青草 发表于 2021-7-2 11:46:11

批处理系列6:查找剩余空间最大的磁盘盘符(终稿)

本帖最后由 青青草 于 2021-7-25 10:48 编辑

现在的硬盘都是大容量,需考虑批处理计算时受到位数的限制,故再次更新如下:

@echo off
setlocal EnableDelayedExpansion
set zero=0000000000000000000000000000000000000000
set size=!zero!1
for /f "tokens=1-3" %%a in ('wmic logicaldisk where "DriveType='3'" get freespace^,name^,size^|find ":"')do (
    for /f "tokens=1,2,3 delims= " %%i in ("%%c") do (
set space=%%a
set free=!zero!!space!
if "!free:~-40!" gtr "!size:~-40!" (
setsize=!free:~-40!
set maxdisk=%%b
set mb=!space!
)
echo 分区%%b   大小:%%c 字节   剩余 !space! 字节
)
)
echo 硬盘剩余最大: 分区 !maxdisk!   剩余: %mb% 字节
pause       利用字符串比较,较好地解决了批处理计算时受位数限制问题,代码较为简洁。位数预设了40位,应该足够了。
    虽然位数预设了40位,足够用了,但总感觉缺点什么;对了,预设40位,还是受到限制,代码不够通用。故修改如下:@echo off
setlocal EnableDelayedExpansion
set maxn=0
set size=0
for /f "tokens=1-3" %%a in ('wmic logicaldisk where "DriveType='3'" get freespace^,name^,size^|find ":"')do (
      set space=%%a
         call :Length space n
            if !n! gtr !maxn! (
                   setmaxn=!n!
                   setsize=!space!
                   set maxdisk=%%b
               )
            if "!n!" EQU "!maxn!" (
                  if "!space!" gtr "!size!" (
                     setsize=!space!
                     set maxdisk=%%b
                   )               
               )
echo 分区%%b   大小:%%c 字节   剩余 !space! 字节
)
echo 硬盘剩余最大: 分区 !maxdisk!   剩余: %size% 字节
pause

:Length
setlocal enabledelayedexpansion
set "$=!%1!#"
set "len="&for %%a in (4096 2048 1024 256 128 64 32 16 8 4 2 1) do (if "!$:~%%a,1!" NEQ "" set/a len+=%%a&set "$=!$:~%%a!" &if "!$:~1!"=="" goto ok)
set "s=!s!fedcba9876543210" &set/a "len+=0x!s:~16,1!"
:ok
endlocal&set/a "%2=%len%"
goto:eof







bfgxp 发表于 2021-7-2 12:10:27

不错,以前一直想要这么一个脚本,虽然后来我用au3实现了。
还是喜欢批处理的直接。

青青草 发表于 2021-7-2 12:18:26

bfgxp 发表于 2021-7-2 12:10
不错,以前一直想要这么一个脚本,虽然后来我用au3实现了。
还是喜欢批处理的直接。

{:1_186:}{:1_186:}

ESD 发表于 2021-7-2 17:05:05

这个代码连setlocal ENABLEDELAYEDEXPANSION都没有加上,你发出来作甚呢?

江南一根葱 发表于 2021-7-3 23:57:11

貌似不行啊,网上找到的其它批处理也不行

江南一根葱 发表于 2021-7-4 00:08:24

echo off
set /a max=0
setlocal EnableDelayedExpansion
title 各分区剩余空间情况
echo.
echo.
echo 磁盘分区 磁盘卷标名 剩余空间(MB)
echo _____________________________________________________
for %%d in (C D E F G H I J K L M N O P Q R S T U V W Z) do (
if exist %%d:\nul (
for /f "tokens=3" %%z in ('dir /-c %%d:\') do set freesize=%%z
set /a freesize=!freesize:~0,-3!/1073>nul
set freesiz=!freesize!
set /a freesize=!freesiz:~-9!
if !freesize! gtr !max! set max=!freesize!&&set maxdisk=%%d:
for /f "tokens=3*" %%v in ('vol %%d:') do set volume=%%w
set volume=!volume!
set volume=!volume:~-20!
echo %%d: !volume! !freesize!
)
)
@echo 剩余空间最大的盘符为%maxdisk% ,可映射为I盘
pause抄了个,可以

青青草 发表于 2021-7-4 14:59:50

江南一根葱 发表于 2021-7-4 00:08
抄了个,可以

剩余空间的大小显示不准确。

青青草 发表于 2021-7-4 18:11:13

bfgxp 发表于 2021-7-2 12:10
不错,以前一直想要这么一个脚本,虽然后来我用au3实现了。
还是喜欢批处理的直接。

已更新,显示剩余空间容量更精确!

青青草 发表于 2021-7-5 09:45:02

ESD 发表于 2021-7-2 17:05
这个代码连setlocal ENABLEDELAYEDEXPANSION都没有加上,你发出来作甚呢?

这么简单的事情,谁不会?自己加上不就得了。

610644034 发表于 2021-7-5 21:03:31

批处理实现起来没有压力啊!

青青草 发表于 2021-7-5 21:23:55

610644034 发表于 2021-7-5 21:03
批处理实现起来没有压力啊!

{:1_195:}

dos时代菜鸟 发表于 2021-7-11 11:01:27

本帖最后由 dos时代菜鸟 于 2021-7-11 11:37 编辑

@echo off
setlocalENABLEDELAYEDEXPANSION
set bit=0
set free1=0
set free2=0
set n=0
echo 找出剩余空间最大的那个分区对应的盘符
echo --------------------------------------
for /f"skip=1 delims=" %%c in (' wmic volume get DriveLetter^,freespace^,Label') do (
    for /f "tokens=1,2,3* delims= " %%i in ("%%c") do (
      if not "%%k"=="" (

            rem 计算当前 Freespace 数值位数
            call:x_bit %%j
            
            set free=%%j
            rem 因为 cmd 只能计算10位数 且小于 2147483647 ,所以先截取 数值后9位,存入Free22
            rem 再截取前面剩下的,如果 当前位数不足9,设置0
            set free22=!free:~-9!
            if !bit1! gtr 9 (set free11=!free:~0,-9!) else (set free11=0)
            
            rem 如果当前 Freespace 数值位数比之前的大,就进一步比较
            if !bit1! geq !bit! (
                set bit=!bit1!
      
                rem 分两段比较 Free1 free2 确定当前 是否为最大。
                if !free11! geq !free1! (
                  if !free11! gtr !free1!set free2=!free22!
                  set free1=!free11!
                  if !free22! geq !free2! (
                        set free2=!free22!
                        set drv=%%i
                        set /a n=n+1
                  )
                )
            )
            if "!drv!"=="%%i" (echo %%i    !free11!,!free22!    *!n!    %%k) else (echo %%i    !free11!,!free22!      %%k)
      )
    )
)
echo -----------------------------------
if not "!drv!"=="" ( echo MAX_FREE_DRV=!drv!      !free1!!free2!) ELSE (echo 没有可用分区!)
pause
goto :eof

:x_bit
rem 用于计算传递过来的 字符串参数 的字符个数。 返回变量 bit1
    set "str1=%1"
    for /l %%r in (0,1,18) do (
      if not "!str1:~%%r,1!"=="" (
            setbit1=%%r
      )
    )
exit /b

引入一个计算数值位数的 办法。用 wimc 获取分区剩余大小,然后比较出来。
预设数值最大 18位,而 cmd 只能计算10位数 且要小于 2147483647,那就 截取下呗。
仅做技术交流,运行效率 不是最好的,但算法 是最传统的。






lpsyuntao 发表于 2021-7-11 18:24:31

感谢分享

plusv 发表于 2021-7-12 14:56:03

dos时代菜鸟 发表于 2021-7-11 11:01
引入一个计算数值位数的 办法。用 wimc 获取分区剩余大小,然后比较出来。
预设数值最大 18位,而 cmd...

>而 cmd 只能计算10位数 且要小于 2147483647
准确的说是 32 位有号整数
Int=   -2147483648(80000000) 到 2147483647(7FFFFFFF)


MS OS 从 Vista 就已进入 64 位,
而 CMD Console 只能支持到32 位有号整数,
已是千年老问题,
MS 都不修.






dos时代菜鸟 发表于 2021-7-13 12:17:19

本帖最后由 dos时代菜鸟 于 2021-7-13 12:21 编辑

plusv 发表于 2021-7-12 14:56
>而 cmd 只能计算10位数 且要小于 2147483647
准确的说是 32 位有号整数
Int=   -2147483648(8000000 ...
if !bit1! gtr 9 (set free11=!free:~0,-9!) else (set free11=0)

改成
if !bit1! geq 9 (set free11=!free:~0,-9!) else (set free11=0)

@echo off
setlocalENABLEDELAYEDEXPANSION
set bit=0
set free1=0
set free2=0
set n=0
echo 找出剩余空间最大的那个分区对应的盘符
echo --------------------------------------
for /f"skip=1 delims=" %%c in (' wmic volume get DriveLetter^,freespace^,Label') do (

    for /f "tokens=1,2,3* delims= " %%i in ("%%c") do (
      if not "%%k"=="" (

            rem 计算当前 Freespace 数值位数
            call:x_bit %%j
            
            set free=%%j
            rem 因为 cmd 只能计算10位数 且小于 2147483647 ,所以先截取 数值后9位,存入Free22
            rem 再截取前面剩下的,如果 当前位数不足9,设置0
            set free22=!free:~-9!
            if !bit1! geq 9 (set free11=!free:~0,-9!) else (set free11=0)
            
            rem 如果当前 Freespace 数值位数比之前的大,就进一步比较
            if !bit1! geq !bit! (
                set bit=!bit1!
      
                rem 分两段比较 Free1 free2 确定当前 是否为最大。
                if !free11! geq !free1! (
                  if !free11! gtr !free1!set free2=!free22!
                  set free1=!free11!
                  if !free22! geq !free2! (
                        set free2=!free22!
                        set drv=%%i
                        set /a n=n+1
                  )
                )
            )
            if "!drv!"=="%%i" (echo %%i    !free11!,!free22!    *!n!    %%k) else (echo %%i    !free11!,!free22!      %%k)
      )
    )
)
echo -----------------------------------
if not "!drv!"=="" ( echo MAX_FREE_DRV=!drv!      !free1!!free2!) ELSE (echo 没有可用分区!)
pause
goto :eof

:x_bit
rem 用于计算传递过来的 字符串参数 的字符个数。 返回变量 bit1
    set "str1=%1"
    for /l %%r in (0,1,18) do (
      if not "!str1:~%%r,1!"=="" (
            setbit1=%%r
      )
    )
exit /b


plusv 发表于 2021-7-13 12:29:17

dos时代菜鸟 发表于 2021-7-13 12:17
if !bit1! gtr 9 (set free11=!free:~0,-9!) else (set free11=0)

改成


于 Windows 7 X64 测试通过.


nttwqz 发表于 2021-7-13 13:47:44

plusv 发表于 2021-7-12 14:56
>而 cmd 只能计算10位数 且要小于 2147483647
准确的说是 32 位有号整数
Int=   -2147483648(8000000 ...

从7的默认cmd到8.1的资管管理器默认cmd和ps,到10的默认ps以及右键默认ps,MS在越来越激进的推荐PS,cmd能不放弃就不错了,我估计绝大部分代码几十年都没动过,更别提改进了,深入研究下,连特么diskpart都一大堆bug。跟分裂的UI一样,10都出来多少年了,依然十分分裂

plusv 发表于 2021-7-13 14:35:33

nttwqz 发表于 2021-7-13 13:47
从7的默认cmd到8.1的资管管理器默认cmd和ps,到10的默认ps以及右键默认ps,MS在越来越激进的推荐PS,cmd ...
MS 很早以前就推 PowerShell 取代 BAT,
我会 C# 所以使用 PowerShell 也没什么难度,
PowerShell 是比较强大没错,
但实际上我不常使用 PowerShell.

原因:
1. PowerShell 依赖 .Net Framework,所以很不通用各 OS.
2. PowerShell 在老机器(我老 PC 12 年)第一次运行约 3-5 秒,很慢.
3. Windows PE 通常没有 .Net Framework/PowerShell.
4. .Net Framework 有版本要求,就像 DLL Hell 一样.

通常:
1. 优先使用 BAT.
2. 功能不足/效率差的就找网上现有的第三方 CMD Console 小程序.
3. 没合适的就自写 CMD Console 小程序.
4. 最后才会使用 PowerShell.

至于 UI,
MS UI 真是越做越丑.

我个人认为的经典
DOS : DOS 6.22
Win9x : Windows 98 第二版
WinNT : Windows XP/Windows 7(使用中,目前使用 12 年)


807979023 发表于 2021-7-13 21:19:36

本帖最后由 807979023 于 2021-7-13 21:34 编辑

转自批处理之家apang大师作品。
加了一句判断,多数代码看不懂,剩余空间的大小显示准确。

@echo off&color 1f&echo.
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=g" %%a in ('cmd /u /c Echo,有') do set "Tab=%%a"
set w=wmic logicaldisk where "DriveType='3'"
set /a max=1
for /f "tokens=1-3" %%a in ('%w% get freespace^,name^,size^|find ":"')do (
set /p=分区%%b%Tab%<nul
call :GetSize %%a000 free
call :GetSize %%c000 size
set /a used=size-free
if !size! gtr 102400 (
    set "G=GB" & set /a size/=1024,used/=1024
) else set "G=MB"
set /a used=1000*used/size
if "!used:~,-1!" == "" set "used=0!used!"
set /p=大小: !size:~,-2!.!size:~-2!!G!%Tab%<nul
set free1=!free!
if !free! gtr 102400 (set /a free/=1024 & set "G=GB") else set "G=MB"
set /p=剩余: !free:~,-2!.!free:~-2!!G!%Tab%<nul
set /p=使用率: !used:~,-1!.!used:~-1!%%<nul & echo,
if !free1! gtr !max! set max=!free1!&&set mb=!free:~,-2!.!free:~-2!!G!&&set bc=%%b
)
echo.&echo 硬盘剩余最大: 分区%bc%    剩余: %mb%
echo.&echo 按任意键退出...&pause >nul&exit

:GetSize
set "num=%1" & set "n=" & set "%2="
for %%a in (16 8 4 2 1) do (
if not "!num:~%%a!"=="" set /a n+=%%a & set "num=!num:~%%a!"
)
set "num=%1" & set /a n-=6
for /l %%a in (!n! -1 1) do (
set "s=!num:~,-%%a!"
if "!s:~,1!" == "0" set "s=!s:~1!"
set /a m=s%%1048576,s/=1048576
set "%2=!%2!!s!"
set "num=!m!!num:~-%%a!"
)
if not defined %2 (
set "%2=!num:~,-1!"
) else if "!%2:~,1!" == "0" set "%2=!%2:~1!"
goto :EOF


plusv 发表于 2021-7-13 23:03:12

807979023 发表于 2021-7-13 21:19
转自批处理之家apang大师作品。
加了一句判断,多数代码看不懂,剩余空间的大小显示准确。

于 Windows 7 X64 测试通过.



807979023 发表于 2021-7-14 10:06:48

plusv 发表于 2021-7-13 23:03
于 Windows 7 X64 测试通过.

请问格式和卷名是怎么加的呀!

807979023 发表于 2021-7-14 10:07:00

本帖最后由 807979023 于 2021-7-14 10:08 编辑

plusv 发表于 2021-7-13 23:03
于 Windows 7 X64 测试通过.

nttwqz 发表于 2021-7-14 14:30:25

dfp /drives /b
貌似是8.1系统独有命令,复制到10下可用

plusv 发表于 2021-7-14 20:55:36

807979023 发表于 2021-7-14 10:06
请问格式和卷名是怎么加的呀!

将 FileSystem,VolumeName 加到 For

807979023 发表于 2021-7-15 13:30:40

加格式和卷名后,xpwin7x32win7x64 测试通过,win10x64失败。

plusv 发表于 2021-7-15 18:28:22

807979023 发表于 2021-7-15 13:30
加格式和卷名后,xpwin7x32win7x64 测试通过,win10x64失败。

807979023> 加格式和卷名后,xpwin7x32win7x64 测试通过,win10x64失败。

我于 Windows XP/Windows 7 X64/Windows 10 X64 都没问题.

=================================================

另外:
我于 Windows XP/Windows 7 X64/Windows 10 X64

1.bat --> 19F 807979023
2.bat --> 12F dos时代菜鸟
3.bat --> 6F 江南一根葱

只有 2.bat --> 12F dos时代菜鸟 由于 Windows XP 不支持 wmic volume,
其它全部都没问题.








807979023 发表于 2021-7-15 19:27:22

plusv 发表于 2021-7-15 18:28
807979023> 加格式和卷名后,xpwin7x32win7x64 测试通过,win10x64失败。

我于 Windows XP/Window ...

哪里改错了?
@echo off&color 1f&echo.
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=g" %%a in ('cmd /u /c Echo,有') do set "Tab=%%a"
set w=wmic logicaldisk where "DriveType='3'"
set /a max=1
for /f "tokens=1-5" %%a in ('%w% get FileSystem^,freespace^,name^,size^,VolumeName^|find ":"')do (
set /p=分区%%c%Tab%<nul
call :GetSize %%b000 free
call :GetSize %%d000 size
set /a used=size-free
if !size! gtr 102400 (
    set "G=GB" & set /a size/=1024,used/=1024
) else set "G=MB"
set /a used=1000*used/size
if "!used:~,-1!" == "" set "used=0!used!"
set /p=大小: !size:~,-2!.!size:~-2!!G!%Tab%<nul
set free1=!free!
if !free! gtr 102400 (set /a free/=1024 & set "G=GB") else set "G=MB"
set /p=剩余: !free:~,-2!.!free:~-2!!G!%Tab%<nul
set /p=使用率: !used:~,-1!.!used:~-1!%%%Tab%<nul
set /p=卷标: %%e%Tab%<nul
set /p=格式: %%a%Tab%<nul & echo,
if !free1! gtr !max! set max=!free1!&&set mb=!free:~,-2!.!free:~-2!!G!&&set bc=%%c
)
echo.&echo 分区剩余最大: 分区%bc%    剩余: %mb%
echo.&echo 按任意键退出...&pause >nul&exit

:GetSize
set "num=%1" & set "n=" & set "%2="
for %%a in (16 8 4 2 1) do (
if not "!num:~%%a!"=="" set /a n+=%%a & set "num=!num:~%%a!"
)
set "num=%1" & set /a n-=6
for /l %%a in (!n! -1 1) do (
set "s=!num:~,-%%a!"
if "!s:~,1!" == "0" set "s=!s:~1!"
set /a m=s%%1048576,s/=1048576
set "%2=!%2!!s!"
set "num=!m!!num:~-%%a!"
)
if not defined %2 (
set "%2=!num:~,-1!"
) else if "!%2:~,1!" == "0" set "%2=!%2:~1!"
goto :EOF

青青草 发表于 2021-7-15 20:21:06

plusv 发表于 2021-7-15 18:28
807979023> 加格式和卷名后,xpwin7x32win7x64 测试通过,win10x64失败。

我于 Windows XP/Window ...

已再次更新代码,麻烦你测试一下。
谢谢!

plusv 发表于 2021-7-16 01:41:33

本帖最后由 plusv 于 2021-7-16 01:47 编辑

807979023 发表于 2021-7-15 19:27
哪里改错了?
我 12 年老 PC,
Windows 7 X64 : 主系统.
Windows XP(在 VMWare 中) : 测试软件.
Windows 10 PE(在 VMWare 中) : 测试软件.
Windows 10 (一台小 NoteBook 中) : 没什么在用,一个月开机一次.

批处理在 Windows XP/Windows 7 X64 测试正常,
下午于 Windows 10 (一台小 NoteBook 中) 测试完 26F 文后就收起来了,
试了两个 Windows 10 PE(在 VMWare 中)无 WMIC,所以无法测试.










plusv 发表于 2021-7-16 01:45:54

青青草 发表于 2021-7-15 20:21
已再次更新代码,麻烦你测试一下。
谢谢!

我 12 年老 PC,
Windows 7 X64 : 主系统.
Windows XP(在 VMWare 中) : 测试软件.
Windows 10 PE(在 VMWare 中) : 测试软件.
Windows 10 (一台小 NoteBook 中) : 没什么在用,一个月开机一次.

批处理在 Windows XP/Windows 7 X64 测试正常,
下午于 Windows 10 (一台小 NoteBook 中) 测试完 26F 文后就收起来了,
试了两个 Windows 10 PE(在 VMWare 中)无 WMIC,所以无法测试.






页: [1] 2
查看完整版本: 批处理系列6:查找剩余空间最大的磁盘盘符(终稿)