【问题标题】:Get Folder Size from Windows Command Line从 Windows 命令行获取文件夹大小
【发布时间】:2012-09-30 14:22:00
【问题描述】:

在 Windows 中是否可以在不使用任何 3rd 方工具的情况下从命令行获取文件夹的大小?

我想要的结果与在 Windows 资源管理器 → 属性中右键单击文件夹时获得的结果相同。

【问题讨论】:

    标签: windows powershell command-line


    【解决方案1】:

    有一个内置的 Windows 工具

    dir /s 'FolderName'
    

    这会打印很多不必要的信息,但最后会是这样的文件夹大小:

     Total Files Listed:
           12468 File(s)    182,236,556 bytes
    

    如果您需要包含隐藏文件夹,请添加/a

    【讨论】:

    • 如果您不需要整数返回值,这是最优雅的解决方案。注意:“/a”开关将在总大小中包括隐藏文件和系统文件。
    • 我猜不可能以一些更有用的单位打印文件大小,比如 kB 或 MB,对吧?
    • 双引号而不是单引号。
    • 只有在我在这里重新排列命令时才有效 - dir 'FolderName'/s
    【解决方案2】:

    您可以递归地添加大小(以下是批处理文件):

    @echo off
    set size=0
    for /r %%x in (folder\*) do set /a size+=%%~zx
    echo %size% Bytes
    

    但是,这有几个问题,因为cmd 仅限于 32 位有符号整数运算。所以它会得到超过 2 GiB 的错误1。此外,它可能会多次计算符号链接和连接,因此它充其量只是一个上限,而不是真实大小(不过,任何工具都会有这个问题)。

    另一种选择是 PowerShell:

    Get-ChildItem -Recurse | Measure-Object -Sum Length
    

    或更短:

    ls -r | measure -sum Length
    

    如果你想要它更漂亮:

    switch((ls -r|measure -sum Length).Sum) {
      {$_ -gt 1GB} {
        '{0:0.0} GiB' -f ($_/1GB)
        break
      }
      {$_ -gt 1MB} {
        '{0:0.0} MiB' -f ($_/1MB)
        break
      }
      {$_ -gt 1KB} {
        '{0:0.0} KiB' -f ($_/1KB)
        break
      }
      default { "$_ bytes" }
    }
    

    你可以直接从cmd使用这个:

    powershell -noprofile -command "ls -r|measure -sum Length"
    

    1 我在批处理文件中确实有一个部分完成的 bignum 库,它至少可以获得任意精度整数加法的权利。我真的应该释放它,我猜 :-)

    【讨论】:

    • Steve,在我看来,PowerShell 比 Unix 更像 Unix,因为大多数核心命令都是正交的。在 Unix 中,du 给出了目录大小,但它所做的只是遍历树并进行总结。可以在像这里这样的管道中非常优雅地表达的东西:-)。所以对于 PowerShell,我通常会寻找如何将高级目标分解为合适的低级操作。
    • 我明白了,它似乎忽略了隐藏文件夹。如果我还想包含隐藏文件夹,则 ls -force -r 有效。
    • folder\* 对我不起作用,我放在该位置的文件夹大小显示为 0 字节,有什么解决方案吗?
    • 更好看的版本:powershell -noprofile -command "'{0:N0}' -f (ls -r|measure -s Length).Sum"
    • @athos:在批处理文件中使用%1 代替folder,或者将参数添加到PowerShell 脚本并将其作为参数添加到Get-ChildItem。但是,如果您对此部分有疑问,也许最好将这些问题作为一个单独的问题提出(因为它与此处的原始问题无关)。
    【解决方案3】:

    Oneliner:

    powershell -command "$fso = new-object -com Scripting.FileSystemObject; gci -Directory | select @{l='Size'; e={$fso.GetFolder($_.FullName).Size}},FullName | sort Size -Descending | ft @{l='Size [MB]'; e={'{0:N2}    ' -f ($_.Size / 1MB)}},FullName"
    

    相同,但仅限 Powershell:

    $fso = new-object -com Scripting.FileSystemObject
    gci -Directory `
      | select @{l='Size'; e={$fso.GetFolder($_.FullName).Size}},FullName `
      | sort Size -Descending `
      | ft @{l='Size [MB]'; e={'{0:N2}    ' -f ($_.Size / 1MB)}},FullName
    

    这应该会产生以下结果:

    Size [MB]  FullName
    ---------  --------
    580,08     C:\my\Tools\mongo
    434,65     C:\my\Tools\Cmder
    421,64     C:\my\Tools\mingw64
    247,10     C:\my\Tools\dotnet-rc4
    218,12     C:\my\Tools\ResharperCLT
    200,44     C:\my\Tools\git
    156,07     C:\my\Tools\dotnet
    140,67     C:\my\Tools\vscode
    97,33      C:\my\Tools\apache-jmeter-3.1
    54,39      C:\my\Tools\mongoadmin
    47,89      C:\my\Tools\Python27
    35,22      C:\my\Tools\robomongo
    

    【讨论】:

    • 有没有办法在基本文件夹中显示所有文件和 Mb 大小?在这种情况下`C:\my\Tools`
    • 另外,当有很多文件夹时它会中断(例如在 C: 驱动器中)
    • 0.00 C:\Windows 我可以为所有文件夹优化这个吗,已经尝试以管理员身份运行
    • 这很好,但它会截断我的组件文件夹名称。完全显示它们的命令是什么?
    • @sean.net 你的意思是在长文件夹的情况下它以“...”结尾吗?这就是ft (Format-Table) 的工作原理。你可以试试fl (Format-List)
    【解决方案4】:

    我建议从 Microsoft 在此链接提供的 Sysinternals Suite 下载实用程序 DU http://technet.microsoft.com/en-us/sysinternals/bb896651

    usage: du [-c] [-l <levels> | -n | -v] [-u] [-q] <directory>
       -c     Print output as CSV.
       -l     Specify subdirectory depth of information (default is all levels).
       -n     Do not recurse.
       -q     Quiet (no banner).
       -u     Count each instance of a hardlinked file.
       -v     Show size (in KB) of intermediate directories.
    
    
    C:\SysInternals>du -n d:\temp
    
    Du v1.4 - report directory disk usage
    Copyright (C) 2005-2011 Mark Russinovich
    Sysinternals - www.sysinternals.com
    
    Files:        26
    Directories:  14
    Size:         28.873.005 bytes
    Size on disk: 29.024.256 bytes
    

    当您使用它时,请查看其他实用程序。它们是每个 Windows 专业人士的救命稻草

    【讨论】:

    • 我猜这几乎不是“没有任何第三方工具”。
    • 哦对,但它认为家庭不应被视为“第三者”。
    • 好吧,当然,但它仍然是一个额外的下载(或者使用\\live.sysinternals.com,如果它仍然存在)。不过,我完全同意,默认情况下应该包含所有 sysinternals 工具。尽管对于许多用途而言,PowerShell 是一个非常值得替代的产品。
    • 有人说 Powershell 吗?请尝试以下操作:"{0:N2}" -f ((Get-ChildItem C:\Temp -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB) + "MB"
    • 我建议大家下载 Mark Russinovich 开发的任何东西 :) 每当我找到可以挽救我生命的工具时,我都会看到这个名字。
    【解决方案5】:

    如果您的计算机中安装了 git(越来越常见),只需打开 MINGW32 并输入:du folder

    【讨论】:

    • 如果你想要人类可读的大小,只有一级子目录,并按大小排序,你可以使用以下命令du -h -d 1 folder | sort -h
    【解决方案6】:

    这是我编写的一个 powershell 代码,用于列出当前目录下所有文件夹的大小和文件数。随意重复使用或根据您的需要进行修改。

    $FolderList = Get-ChildItem -Directory
    foreach ($folder in $FolderList)
    {
        set-location $folder.FullName
        $size = Get-ChildItem -Recurse | Measure-Object -Sum Length
        $info = $folder.FullName + "    FileCount: " + $size.Count.ToString() + "   Size: " + [math]::Round(($size.Sum / 1GB),4).ToString() + " GB"
        write-host $info
    }
    

    【讨论】:

    • 为我工作。如果您在无头服务器上很有用。
    • 简洁优雅!我的版本:$FolderList = Get-ChildItem -Directory -Force; $data = foreach ($folder in $FolderList) { set-location $folder.FullName; $size = Get-ChildItem -Recurse -Force | Measure-Object -Sum Length; $size | select @{n="Path"; e={$folder.Fullname}}, @{n="FileCount"; e={$_.count}}, @{n="Size"; e={$_.Sum}} } 这将提供对象(更多 Powershell-ish),'FileCount' 和 'Size' 是整数(因此您可以稍后处理它们,如果需要),并且 'Size' 以字节为单位,但您可以轻松使用$Data.Size / 1GB 将其转换为 GB(或您想要的单位)。
    • 或单行:$Data = dir -Directory -Force | %{ $CurrentPath = $_.FullName; Get-ChildItem $CurrentPath -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Sum Length | select @{n="Path"; e={$CurrentPath}}, @{n="FileCount"; e={$_.count}}, @{n="Size"; e={$_.Sum}} }
    • 我最喜欢这个,但set-location 不是不必要的吗?你可以直接去Get-ChildItem $folder.FullName,这样你就可以从另一边出来,而不会改变你下面的当前目录。
    • 谢谢@BenderBoy。最好去掉set-location,直接使用Get-ChildItem $folder.FullName
    【解决方案7】:

    我建议使用我编写的https://github.com/aleksaan/diskusage 实用程序。非常简单而且很有帮助。而且速度非常快。

    只需输入一个命令shell

    diskusage.exe -path 'd:/go; d:/Books'
    

    并获取按大小排列的文件夹列表

    1.|目录:d:/go |大小:325.72 Mb |深度:1 2.|目录:d:/书籍 |大小:14.01 Mb |深度:1

    这个例子是在 272ms 在 HDD 上执行的。

    您可以增加子文件夹的深度进行分析,例如:

    diskusage.exe -path 'd:/go; d:/Books' -depth 2
    

    不仅可以获取选定文件夹的大小,还可以获取其子文件夹的大小

    1.|目录:d:/go |大小:325.72 Mb |深度:1 2.|目录:d:/go/pkg |大小:212.88 Mb |深度:2 3.|目录:d:/go/src |大小:62.57 Mb |深度:2 4.|目录:d:/go/bin |大小:30.44 Mb |深度:2 5.|目录:d:/书籍/国际象棋 |大小:14.01 Mb |深度:2 6.|目录:d:/书籍 |大小:14.01 Mb |深度:1 7.|目录:d:/go/api |大小:6.41 Mb |深度:2 8.|目录:d:/go/test |大小:5.11 Mb |深度:2 9.|目录:d:/go/doc |大小:4.00 Mb |深度:2 10.|目录:d:/go/misc |大小:3.82 Mb |深度:2 11.|目录:d:/go/lib |大小:358.25 KB |深度:2

    *** 服务器上的 3.5Tb 已扫描 3m12s**

    【讨论】:

    • 新版本发布! github.com/aleksaan/diskusage 改进:1) 正确使用符号链接的大小 2) 或有关分析对象的所有信息
    • 2.0.2 版本发布! github.com/aleksaan/diskusage/releases/tag/v2.0.2 - 配置文件而不是内联参数 - 简单使用模式(将 diskusage 可执行文件复制到任何文件夹,运行它并获取结果) - 正确的结果输出(正确的行尾符号 win/unix) - 将结果保存到文件或获取控制台模式(选项“tofile”)
    • 请注意您是作者。 (来自stackoverflow.com/help/promotion“但是,您必须在回答中披露您的从属关系。”
    • 是的,我是 github.com/aleksaan/diskusage 程序的作者
    • 2.1.0 版本已发布。 github.com/aleksaan/diskusage/releases/tag/v2.1.0 - 内存消耗优化 - 减少分析时间 - 错误修复
    【解决方案8】:

    试试:

    SET FOLDERSIZE=0
    FOR /F "tokens=3" %A IN ('DIR "C:\Program Files" /a /-c /s ^| FINDSTR /C:" bytes" ^| FINDSTR /V /C:" bytes free"') DO SET FOLDERSIZE=%A
    

    如果在批处理文件中使用,请将 C:\Program Files 更改为您想要的任何文件夹并将 %A 更改为 %%A

    它返回整个文件夹的大小,包括子文件夹和隐藏文件和系统文件,适用于超过 2GB 的文件夹

    它确实会写入屏幕,因此如果您不想这样做,则必须使用临时文件。

    【讨论】:

      【解决方案9】:

      此代码经过测试。你可以再检查一遍。

      @ECHO OFF
      CLS
      SETLOCAL
      ::Get a number of lines contain "File(s)" to a mytmp file in TEMP location.
      DIR /S /-C | FIND "bytes" | FIND /V "free" | FIND /C "File(s)" >%TEMP%\mytmp
      SET /P nline=<%TEMP%\mytmp
      SET nline=[%nline%]
      ::-------------------------------------
      DIR /S /-C | FIND "bytes" | FIND /V "free" | FIND /N "File(s)" | FIND "%nline%" >%TEMP%\mytmp1
      SET /P mainline=<%TEMP%\mytmp1
      CALL SET size=%mainline:~29,15%
      ECHO %size%
      ENDLOCAL
      PAUSE
      

      【讨论】:

      • 谢谢,它适用于小于 1GB 的文件夹,但例如,我有一个 3,976,317,115 字节(3.70GB)的文件夹,脚本返回给我这个字符串“)932”,你知道为什么吗?
      【解决方案10】:

      我猜这只有在目录是相当静态的并且它的内容在两个 dir 命令的执行之间没有改变的情况下才有效。也许是一种将其组合成一个命令以避免这种情况的方法,但这符合我的目的(我不想要完整的列表;只是摘要)。

      GetDirSummary.bat 脚本:

      @echo off
      rem  get total number of lines from dir output
      FOR /F "delims=" %%i IN ('dir /S %1 ^| find "asdfasdfasdf" /C /V') DO set lineCount=%%i
      rem  dir summary is always last 3 lines; calculate starting line of summary info
      set /a summaryStart="lineCount-3"
      rem  now output just the last 3 lines
      dir /S %1 | more +%summaryStart%
      

      用法:

      GetDirSummary.bat c:\temp

      输出:

       Total Files Listed:
                22 File(s)         63,600 bytes
                 8 Dir(s)  104,350,330,880 bytes free
      

      【讨论】:

        【解决方案11】:

        我的 git 发行版获得了 du.exe。另一个地方可能是前面提到的微软或Unxutils

        一旦你的路径中有 du.exe。这是你的fileSizes.bat :-)

        @echo ___________
        @echo DIRECTORIES
        @for /D %%i in (*) do @CALL du.exe -hs "%%i"
        @echo _____
        @echo FILES
        @for %%i in (*) do @CALL du.exe -hs "%%i"
        @echo _____
        @echo TOTAL
        @du.exe -sh "%CD%"
        

        ___________
        DIRECTORIES
        37M     Alps-images
        12M     testfolder
        _____
        FILES
        765K    Dobbiaco.jpg
        1.0K    testfile.txt
        _____
        TOTAL
        58M    D:\pictures\sample
        

        【讨论】:

          【解决方案12】:

          我认为您唯一的选择是 diruse(高度支持的第 3 方解决方案):

          Get file/directory size from command line

          不幸的是,Windows CLI 的限制非常严格,您也可以安装 Cygwin,与 cmd 相比,这是一个梦想。这将使您可以访问移植的 Unix 工具 du,它是 windows 上 diruse 的基础。

          抱歉,我无法使用可在本机 cli 上运行的命令直接回答您的问题。

          【讨论】:

          • 如果你只需要du,那么 Cygwin 就太过分了。只需使用GnuWin32
          • 确实有点矫枉过正,但也很棒。为您在@joey 上方的帖子+1(没有代表从字面上做到这一点:()
          • 在我的拙见中,Cygwin 可能对某些人有用,但它远非令人敬畏而且相当可怕。但我猜 Unix 用户对 Wine 也是这么说的。
          • "wine" - 不寒而栗,我在我的开发笔记本电脑上使用 Cygwin,因为在 linux 下电池寿命令人震惊,并且在其上运行 VM 不方便。这需要一些设置,但 Cygwin 对于我们这些错过 Windows 中的 nix shell 的人来说非常棒,我个人不喜欢 Powershell,但我可能不得不检查 GnuWin。谢谢@Joey。
          【解决方案13】:

          ::获取 Dir 命令返回的行数(/-c 消除数字分隔符:.,) ["Tokens = 3" 只看 Dir 中每一行的第三列]

          FOR /F "tokens=3" %%a IN ('dir /-c "%folderpath%"') DO set /a i=!i!+1

          倒数第二行的数字,这里是文件总和的字节数:

          set /a line=%i%-1
          

          最后得到倒数第二行-第3列的字节数:

          set i=0
          FOR /F "tokens=3" %%a IN ('dir /-c "%folderpath%"') DO (
            set /a i=!i!+1
            set bytes=%%a
            If !i!==%line% goto :size  
          )
          :size
          echo %bytes%
          

          由于它不使用单词搜索,所以不会有语言问题。

          限制:

          • 仅适用于小于 2 GB 的文件夹(cmd 不处理超过 32 位的数字)
          • 不读取内部文件夹的字节数。

          【讨论】:

            【解决方案14】:

            以下脚本可用于获取和累积给定文件夹下每个文件的大小。
            文件夹路径 %folder% 可以作为此脚本的参数 (%1)。
            最终,结果保存在参数%filesize%

            @echo off
            SET count=1
            SET foldersize=0
            FOR /f "tokens=*" %%F IN ('dir /s/b %folder%') DO (call :calcAccSize "%%F")
            echo %filesize%
            GOTO :eof
            
            :calcAccSize
             REM echo %count%:%1
             REM set /a count+=1
             set /a foldersize+=%~z1
             GOTO :eof
            

            注意:calcAccSize方法也可以打印文件夹的内容(上例中注释)

            【讨论】:

              【解决方案15】:

              因此,这是您最初要求的两种请求的解决方案。 它将提供人类可读的文件大小,而不会受到每个人都遇到的文件大小限制。兼容 Win Vista 或更新版本。 XP 仅在安装了 Robocopy 时可用。只需在此批处理文件上放置一个文件夹或使用下面提到的更好的方法。

              @echo off
              setlocal enabledelayedexpansion
              set "vSearch=Files :"
              
              For %%i in (%*) do (
                  set "vSearch=Files :"
                  For /l %%M in (1,1,2) do ( 
                      for /f "usebackq tokens=3,4 delims= " %%A in (`Robocopy "%%i" "%%i" /E /L /NP /NDL /NFL ^| find "!vSearch!"`) do (
                          if /i "%%M"=="1" (
                              set "filecount=%%A"
                              set "vSearch=Bytes :"
                          ) else (
                              set "foldersize=%%A%%B"
                          )
                      )
                  )
                  echo Folder: %%~nxi FileCount: !filecount! Foldersize: !foldersize!
                  REM remove the word "REM" from line below to output to txt file
                  REM echo Folder: %%~nxi FileCount: !filecount! Foldersize: !foldersize!>>Folder_FileCountandSize.txt
              )
              pause
              

              为了能够方便地使用这个批处理文件,请将它放在您的 SendTo 文件夹中。 这将允许您右键单击一个文件夹或文件夹选择,单击 SendTo 选项,然后选择此批处理文件。

              要在您的计算机上找到 SendTo 文件夹,最简单的方法是打开 cmd 然后按原样复制此行。

              explorer C:\Users\%username%\AppData\Roaming\Microsoft\Windows\SendTo
              
              

              【讨论】:

              • 对于任何担心 Robocopy 会移动文件的人......不要。 /l 选项仅列出。另外,Robocopy 不是第 3 方,Windows Vista 以上默认安装 Robocopy,XP 需要安装。
              • 感谢您的加入。很高兴看到这个帖子仍然引起注意 ;-) 可能想要添加如何安装 robocopy(很棒的工具!)。
              【解决方案16】:

              以下单行可用于确定文件夹的大小。

              帖子是Github Actions格式,说明使用的是哪种类型的shell。

              shell: pwsh
              run: |
                Get-ChildItem -Path C:\temp -Recurse | Measure-Object -Sum Length
              
              
              shell: cmd
              run: |
                powershell -noprofile -command "'{0:N0}' -f (ls C:\temp -r | measure -s Length).Sum"
              

              【讨论】:

                【解决方案17】:

                打开windows CMD并运行follow命令

                dir /s c:\windows
                

                【讨论】:

                  【解决方案18】:

                  我解决了类似的问题。此页面中的某些方法很慢,而某些方法在多语言环境中存在问题(均假设为英语)。 我发现在 cmd 中使用 vbscript 的简单解决方法。它在 W2012R2 和 W7 中进行了测试。

                  >%TEMP%\_SFSTMP$.VBS ECHO/Set objFSO = CreateObject("Scripting.FileSystemObject"):Set objFolder = objFSO.GetFolder(%1):WScript.Echo objFolder.Size
                  FOR /F %%? IN ('CSCRIPT //NOLOGO %TEMP%\_SFSTMP$.VBS') DO (SET "S_=%%?"&&(DEL %TEMP%\_SFSTMP$.VBS))
                  

                  它设置环境变量S_。当然,您可以将最后一行更改为直接显示结果,例如

                  FOR /F %%? IN ('CSCRIPT //NOLOGO %TEMP%\_SFSTMP$.VBS') DO (ECHO "Size of %1 is %%?"&&(DEL %TEMP%\_SFSTMP$.VBS))
                  

                  您可以将其用作子程序或单独的 cmd。参数是用引号括起来的测试文件夹的名称。

                  【讨论】:

                    【解决方案19】:

                    获取总大小的最简单方法是 powershell,但仍然受限于长度超过 260 个字符的路径名不包含在总大小中

                    【讨论】:

                    • 这是一个糟糕的答案。什么是命令行或代码?
                    猜你喜欢
                    • 2019-10-29
                    • 2012-08-21
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-04-23
                    • 1970-01-01
                    • 2020-02-01
                    相关资源
                    最近更新 更多