Board logo

标题: [文本处理] 批处理如何提取文件夹大小并输出? [打印本页]

作者: wang5185244    时间: 2014-8-25 20:33     标题: 批处理如何提取文件夹大小并输出?

提取路径下文件夹大小
我知道%%~Z是文件大小
怎么批处理提取文件夹大小啊
作者: CrLf    时间: 2014-8-26 00:22

这个用 vbs 比较快:
  1. http://bbs.bathome.net/viewthread.php?tid=25682
复制代码

作者: terse    时间: 2014-8-26 11:26

  1. @if(0)==(0) echo off
  2. CScript.exe /NoLogo /E:JScript %0
  3. pause & exit
  4. @end
  5. var n=1024,m=1048576,fso=new ActiveXObject("Scripting.FileSystemObject");
  6. var Folder=fso.GetFolder(WScript.Arguments.Count()?WScript.Arguments.Item(0):".");
  7. for(var e=new Enumerator(Folder.SubFolders);!e.atEnd();e.moveNext()){
  8.    var f=e.item();
  9.    var Size=f.Size;
  10.    switch(true){
  11.       case Size<n :
  12.          WScript.Echo(f.Name,'\t' + Size,' Byte');
  13.          break;
  14.       case Size<m :
  15.           WScript.Echo(f.Name,'\t' + (Size/n).toFixed(2),' KB');
  16.           break;   
  17.       default :
  18.           WScript.Echo(f.Name,'\t' + (Size/m).toFixed(2),' MB');
  19.    }
  20. }
复制代码

作者: wang5185244    时间: 2014-8-26 20:37

回复 3# terse


大神,运行出现这错误,什么原因啊~怎么输出结果
作者: terse    时间: 2014-8-27 13:16

回复 4# wang5185244
加个判断试试呢
系统文件夹还是权限不够
  1. @if(0)==(0) echo off
  2. CScript.exe /NoLogo /E:JScript %0 >_dir.txt
  3. pause & exit
  4. @end
  5. var n=1024,m=1048576,fso=new ActiveXObject("Scripting.FileSystemObject");
  6. var Folder=fso.GetFolder(WScript.Arguments.Count()?WScript.Arguments.Item(0):".");
  7. for(var e=new Enumerator(Folder.SubFolders);!e.atEnd();e.moveNext()){
  8.    var f=e.item();
  9.    if (f.Name!='System Volume Information') {
  10.      if(!(f.attributes%2)){
  11.        var Size=f.size;
  12.        switch(true){
  13.           case Size<n :
  14.              var s = Size + ' Byte';
  15.              break;
  16.           case Size<m :
  17.              var s = (Size/n).toFixed(2) + ' KB';
  18.              break;   
  19.           default :
  20.              var s = (Size/m).toFixed(2) + ' MB';
  21.        }
  22.        WScript.Echo(f.Name+'\t' + s);
  23.      }
  24.    }
  25. }
复制代码

作者: CrLf    时间: 2014-8-27 13:23

个人喜欢用 SpaceSniffer 查看目录大小,直观、方便,可惜好像没有命令行下的代替工具
作者: terse    时间: 2014-8-28 01:33

回复 4# wang5185244
纯p效率够不
  1. @echo off&setlocal enabledelayedexpansion
  2. set m=1048576
  3. (for /f "tokens=*" %%i in ('dir /ad /b') do (
  4.     set size=000
  5.     for /f "eol=0tokens=3" %%j in ('dir /s/a/-c "%%i" 2^>nul^| findstr /i "个文件.*字节$"') do set "size=%%j00"
  6.     if !size! geq 102400 (
  7.        if !size! geq 104857600 (
  8.           set s=MB
  9.           set t=!size!
  10.           set len=!t:~9!98765432100
  11.           set /alen=9+!len:~10,1!
  12.           set/a "r=!t:~,8!%%m,size=!t:~,8!/m"
  13.           for /l %%j in (8 1 !len!) do (
  14.               set/a "q=!r!!t:~%%j,1!/m,r=!r!!t:~%%j,1!%%m"
  15.               set "size=!size!!q!"
  16.           )
  17.           if !size! geq 102400 set s=GB&set /asize/=1024
  18.        ) else set s=KB&set /asize/=1024
  19.     ) else set s=Byte
  20.     echo %%i !size:~,-2!.!size:~-2! !s!
  21. ))>DIR_.TXT
  22. start "" DIR_.TXT
复制代码

作者: CrLf    时间: 2014-8-28 02:05

回复 7# terse


    dir 显示的是不含子目录的大小吧
作者: terse    时间: 2014-8-28 11:38

回复 8# CrLf
这里显示的和右键一致
不清楚楼主是否要显示子目录 如显示子目录 dir 加参数 /s
作者: CrLf    时间: 2014-8-28 15:09

回复 9# terse


    xp 和 win7 下测试都只是当前目录下的文件大小总和呀
作者: terse    时间: 2014-8-28 15:47

回复 10# CrLf
难道环境问题?
我这里WIN7 和 XP 都正常显示
作者: CrLf    时间: 2014-8-28 16:10

回复 11# terse


    我对 %windir% 运行了一下兄台的脚本,返回的是
  1. addins 0.00 Byte
  2. AppCompat 0.00 Byte
  3. AppPatch 0.00 Byte
  4. assembly 0.00 Byte
  5. BitLockerDiscoveryVolumeContents 0.00 Byte
  6. Boot 0.00 Byte
  7. Branding 0.00 Byte
  8. CSC 0.00 Byte
  9. Cursors 0.00 Byte
  10. debug 0.00 Byte
  11. diagnostics 0.00 Byte
  12. DigitalLocker 0.00 Byte
  13. Downloaded Program Files 0.00 Byte
  14. EasyRecovery 0.00 Byte
  15. en-US 0.00 Byte
  16. Fonts 0.00 Byte
  17. Globalization 0.00 Byte
  18. Help 0.00 Byte
  19. IME 0.00 Byte
  20. inf 0.00 Byte
  21. Installer 0.00 Byte
  22. L2Schemas 0.00 Byte
  23. LiveKernelReports 0.00 Byte
  24. Logs 0.00 Byte
  25. Media 0.00 Byte
  26. Microsoft.NET 0.00 Byte
  27. Minidump 0.00 Byte
  28. ModemLogs 0.00 Byte
  29. NU_DATA 0.00 Byte
  30. Offline Web Pages 0.00 Byte
  31. Panther 0.00 Byte
  32. PCHEALTH 0.00 Byte
  33. Performance 0.00 Byte
  34. PLA 0.00 Byte
  35. PolicyDefinitions 0.00 Byte
  36. Prefetch 0.00 Byte
  37. pss 0.00 Byte
  38. Registration 0.00 Byte
  39. RemotePackages 0.00 Byte
  40. rescache 0.00 Byte
  41. Resources 0.00 Byte
  42. SchCache 0.00 Byte
  43. schemas 0.00 Byte
  44. security 0.00 Byte
  45. ServiceProfiles 0.00 Byte
  46. servicing 0.00 Byte
  47. Setup 0.00 Byte
  48. ShellNew 0.00 Byte
  49. SoftwareDistribution 0.00 Byte
  50. Speech 0.00 Byte
  51. SUA 0.00 Byte
  52. Sun 0.00 Byte
  53. system 0.00 Byte
  54. System32 0.00 Byte
  55. TAPI 0.00 Byte
  56. Tasks 0.00 Byte
  57. temp 0.00 Byte
  58. tracing 0.00 Byte
  59. twain_32 0.00 Byte
  60. Vss 0.00 Byte
  61. Web 0.00 Byte
  62. WICCodecs 0.00 Byte
  63. winsxs 0.00 Byte
  64. zh-CN 0.00 Byte
复制代码

作者: terse    时间: 2014-8-28 16:32

回复 12# CrLf
先谢CrLf兄的测试
我这边同样%windir%测试正常 猜测是环境问题 难道CrLf兄 不是中文环境?那样的话 FINDSTR 搜索关键词 有问题
作者: CrLf    时间: 2014-8-28 16:50

回复 13# terse


是中文环境,这是 dir /a /-c %windir% 输出内容的末尾部分
  1.               63 个文件       10527174 字节
  2.               66 个目录     5462437888 可用字节
复制代码
terse 兄那边能直接获取整个文件夹的大小倒是让我感觉非常怪异,因为昨天搜了一下,好像没有直接获取目录大小的手段,连 api 都没有,看到的方案都是遍历
如果 dir 是以逐层遍历的办法合计文件夹的总大小,速度应该很慢才是,那 dir /s 的时候岂不是慢得恐怖了
如果我来设计 cmd.exe,也不会默认返回子文件总字节数,最多提供一个可选开关来让用户自行启用
另,我的磁盘格式是 ntfs
作者: 523066680    时间: 2014-8-28 17:42

本帖最后由 523066680 于 2014-8-28 17:46 编辑

以前写过一个挺繁琐的脚本,列出当前子目录大小,可以通过编号选择
进入某个目录继续列举进一层的目录大小。我用来辅助寻找较大的目录。可能有些不精准的地方吧
  1. ::Show Each Folder Size with Percent
  2. ::     via 523066680, 2013-08
  3. ::维护记录:
  4. ::1、文件夹名称里存在"%"时被脱逸而导致的错误
  5. ::2、截取的一兆以上的Size进行*1000000/(1024*1024)
  6. ::3、输入open 或者open 编号,打开当前或者对应目录
  7. @echo off
  8. setlocal enabledelayedexpansion
  9. set "back= "
  10. for /l %%a in (1,1,8) do (
  11.     set back=!back!!back!
  12. )
  13. echo 注:以下统计仅为数值截取的大致结果。
  14. :start
  15. echo 当前目录:"%cd%"
  16. for /f "tokens=1" %%a in ('dir /ad ^|find "个目录"') do (
  17.      set all=%%a
  18. )
  19. if "%all%"=="2" (echo 没有子目录,返回上一层 &cd .. &goto :input)
  20. ::关键变量初始化
  21. set /a i=0, Si[0]=0
  22. ::逐个调用
  23. for /f "tokens=*" %%a in ('dir /ad /b') do (
  24.    set TPath=%%a
  25.    call :deal
  26. )
  27. call :ShowDetail
  28. pause
  29. exit
  30. :deal
  31.   set /a i+=1, ia=i-1, ix=i*100/all
  32.   set /p inp=!back!%ix%%% "!TPath!" <nul
  33.   
  34.   for /f "tokens=3" %%a in ('dir /a /-c /s "!TPath!" ^|find " 个文件"') do (
  35.       set bytes=000000000000%%a
  36.       set bytes=!bytes:~-12!
  37.       set MB=%%a
  38.   )
  39.   if "%MB:~6%"=="" (
  40.       set MB=    ^<1
  41.   ) else (
  42.       set /a RealMB=!MB:~0,-6!*1000/1024*1000/1024
  43.       set MB=      !RealMB!
  44.   )
  45.   rem 对齐
  46.   set MB=!MB:~-6!
  47.   
  48.   rem 插入排序
  49.   for /l %%a in (%ia%,-1,0) do (
  50.       set /a A2=%%a+1
  51.       if !bytes! lss !Si[%%a]! (
  52.    set Si[!A2!]=!Si[%%a]!
  53.    set Sj[!A2!]=!Sj[%%a]!
  54.         set Sk[!A2!]=!Sk[%%a]!
  55.       ) else (
  56.    set Si[!A2!]=!bytes!
  57.    set Sj[!A2!]=!TPath!
  58.         set Sk[!A2!]=!MB!
  59.    goto :Out
  60.       )
  61.   )
  62.   :Out
  63.   goto :eof
  64. :ShowDetail
  65.   set /p inp=%back%<nul
  66.   for /l %%a in (1,1,%i%) do (
  67.       echo %%a !Sk[%%a]! MB  !Sj[%%a]!
  68.   )
  69.   echo,
  70.   :input
  71.   set "input="
  72.   set /p input=进入某目录请输入对应编号(exit退出):
  73.   if "%input%"=="exit" (exit)
  74.   if "%input%"=="prev" (cd .. &goto :start)
  75.   if "%input:~0,4%"=="open" (
  76.       if "%input:~4%"=="" (
  77.           start explorer "%cd%"
  78.       ) else (
  79.           if defined Sj[%input:~5%] (
  80.               start explorer "!Sj[%input:~5%]!"
  81.           ) else (
  82.               echo 请输入正确的编号
  83.           )
  84.       )
  85.       goto :input
  86.   )
  87.   if not defined Si[%input%] (
  88.       echo 输入错误
  89.       goto :input
  90.   ) else (
  91.       set next=!Sj[%input%]!
  92.   )
  93.   cd %next%
  94.   goto :start
复制代码
示例目录 Dev-Cpp ,过程中带简单的扫描进度显示:

───────────┐
当前目录:"D:\Dev-Cpp"│
23% "Help"            │
───────────┘


────────────────────┐
                                        │
注:以下统计仅为数值截取的大致结果。    │
当前目录:"D:\Dev-Cpp"                  │
1           <1 MB  Packages             │
2           <1 MB  Templates            │
3           <1 MB  Examples             │
4           <1 MB  Icons                │
5           <1 MB  Lang                 │
6           <1 MB  Help                 │
7            1 MB  mingw32              │
8            5 MB  include              │
9            7 MB  libexec              │
10          10 MB  bin                  │
11          21 MB  lib                  │
                                        │
进入某目录请输入对应编号(exit退出):11 │
当前目录:"D:\Dev-Cpp\lib"              │
1           <1 MB  gcc                  │
2            5 MB  debug                │
                                        │
进入某目录请输入对应编号(exit退出):   │
────────────────────┘

作者: terse    时间: 2014-8-28 17:46

回复 14# CrLf
这里要加 /s 得到 最后得到 %windir%   9909141116 字节 这个应该是总大小吧
CrLf 兄 再对照 右键属性 看大小是否一致
我这里显示
  1.                56690 个文件     9909141116 字节
  2.            32485 个目录    24819781632 可用字节
复制代码

作者: CrLf    时间: 2014-8-28 17:56

回复 16# terse


    噢!测试无误,原来还可以这样
作者: wang5185244    时间: 2014-8-29 23:36

回复 2# CrLf


    dir提取的是文件大小,文件夹是汇总的
作者: 科零仿佛    时间: 2020-3-1 18:25

回复 15# 523066680


    大佬,怎么选择指定的目录啊
作者: 523066680    时间: 2020-3-2 22:32

回复 19# 科零仿佛


    现在?推荐 磁盘占用可视化工具:SpaceSniffer
作者: 半世纪    时间: 2023-7-5 10:05

回复 15# 523066680


    大佬,找管理员修改了下你的代码,可以不用提取隐藏文件夹:
::Show Each Folder Size with Percent
::     via 523066680, 2023-07
::维护记录:
::1、文件夹名称里存在"%"时被脱逸而导致的错误
::2、截取的一兆以上的Size进行*1000000/(1024*1024)
::3、输入open 或者open 编号,打开当前或者对应目录

@echo off
setlocal enabledelayedexpansion
set "back= "
for /l %%a in (1,1,8) do (
    set back=!back!!back!
)
echo 注:以下统计仅为数值截取的大致结果。

:start
echo 当前目录:"%cd%"
for /f "tokens=1" %%a in ('dir /ad ^|find "个目录"') do (
     set all=%%a
)
if "%all%"=="2" (echo 没有子目录,返回上一层 &cd .. &goto :input)

::关键变量初始化
set /a i=0, Si[0]=0

::逐个调用
for /d %%a in (*) do (
   set TPath=%%a
   call :deal
)

call :ShowDetail
pause
exit

:deal
  set /a i+=1, ia=i-1, ix=i*100/all
  set /p inp=!back!%ix%%% "!TPath!" <nul
  
  for /f "tokens=3" %%a in ('dir /a /-c /s "!TPath!" ^|find " 个文件"') do (
      set bytes=000000000000%%a
      set bytes=!bytes:~-12!
      set MB=%%a
  )
  if "%MB:~6%"=="" (
      set MB=    ^<1
  ) else (
      set /a RealMB=!MB:~0,-6!*1000/1024*1000/1024
      set MB=      !RealMB!
  )
  rem 对齐
  set MB=!MB:~-6!

  
  rem 插入排序
  for /l %%a in (%ia%,-1,0) do (
      set /a A2=%%a+1
      if !bytes! lss !Si[%%a]! (
          set Si[!A2!]=!Si[%%a]!
          set Sj[!A2!]=!Sj[%%a]!
        set Sk[!A2!]=!Sk[%%a]!
      ) else (
          set Si[!A2!]=!bytes!
          set Sj[!A2!]=!TPath!
        set Sk[!A2!]=!MB!
          goto :Out
      )
  )
  :Out
  goto :eof

:ShowDetail
  set /p inp=%back%<nul
  for /l %%a in (1,1,%i%) do (
      echo %%a        !Sk[%%a]! MB  !Sj[%%a]!
  )
  echo,
  :input
  set "input="
  set /p input=进入某目录请输入对应编号(exit退出):
  if "%input%"=="exit" (exit)
  if "%input%"=="prev" (cd .. &goto :start)
  if "%input:~0,4%"=="open" (
      if "%input:~4%"=="" (
          start explorer "%cd%"
      ) else (
          if defined Sj[%input:~5%] (
              start explorer "!Sj[%input:~5%]!"
          ) else (
              echo 请输入正确的编号
          )
      )
      goto :input
  )
  if not defined Si[%input%] (
      echo 输入错误
      goto :input
  ) else (
      set next=!Sj[%input%]!
  )
  cd %next%
  goto :start
作者: smss    时间: 2024-6-4 11:32

回复  wang5185244
纯p效率够不
terse 发表于 2014-8-28 01:33

大于1M小于10M的显示不对
作者: aloha20200628    时间: 2024-6-5 11:12

本帖最后由 aloha20200628 于 2024-6-5 11:50 编辑


十年后再看本帖的解法还是两条最简之道,纯P方案和调用powershell方案(以下两段代码均存为批处理脚本运行)
对比了二者当输出结果一致时的稳定用时比例(须系统硬盘搜索缓存完全预热后),约为1:3
体量较大的实测目录包含约3,000个子目录,约30,000个文件,二者对指定目录统计其总量时均计入系统文件和隐藏文件。
  1. @echo off &dir /a/s/-c "%~1"|findstr /ric:" 个文件 ">0.0
  2. for /f "tokens=3 delims= " %%z in (0.0) do set "z=%%z"
  3. echo,%z%&del/q 0.0&pause&exit/b
复制代码
  1. powershell "(gci '%~1' -force -recurse -erroraction silentlycontinue | measure length -s).sum"
  2. pause&exit/b
复制代码





欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2