在Windows中,是否可以使用命令行获取文件夹的大小而不使用任何第三方工具?
我希望获得与在Windows资源管理器中右键单击文件夹→属性时相同的结果。
在Windows中,是否可以使用命令行获取文件夹的大小而不使用任何第三方工具?
我希望获得与在Windows资源管理器中右键单击文件夹→属性时相同的结果。
有一个 内置的Windows工具 可以做到这一点:
dir /s 'FolderName'
这将打印出许多不必要的信息,但结果将是文件夹的大小,如下所示:
Total Files Listed:
12468 File(s) 182,236,556 bytes
如果您需要包含隐藏文件夹,请添加/a
。
你可以递归地累加大小(以下是批处理文件):
@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我确实有一个未完成的大数库在批处理文件中,它至少正确地实现了任意精度的整数加法。我想我应该把它发布出来。
%1
代替folder
,或者在PowerShell脚本中添加一个参数,并将其作为参数添加到Get-ChildItem
中。但是,如果您在这方面遇到问题(因为它与原始问题无关),也许最好单独提出此类问题。 - Joey一句话概括:
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
C:\my\Tools\
- Raunak Thomasft
(Format-Table
) 的工作方式。你可以尝试使用 fl
(Format-List
)。 - frizik我建议从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 是一个非常值得推荐的替代品。 - Joeydu folder
。du -h -d 1 文件夹 | sort -h
。 - vard这里有一段我编写的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="路径"; e={$folder.Fullname}}, @{n="文件数"; e={$_.count}}, @{n="大小"; e={$_.Sum}} }
这将提供对象(更符合PowerShell的风格),'FileCount'和'Size'是整数(因此您可以在需要时对它们进行处理),'Size'以字节为单位,但您可以使用 $Data.Size / 1GB
轻松将其转换为GB(或您想要的单位)。 - curropar$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}} }
- curroparset-location
是不是多余的?你可以直接使用 Get-ChildItem $folder.FullName
,这样你就可以在不改变当前目录的情况下完成操作。 - BenderBoyset-location
并直接使用Get-ChildItem $folder.FullName
。 - Ryan Lee我建议使用我编写的https://github.com/aleksaan/diskusage实用工具。非常简单和有用。而且速度很快。
只需在命令行中键入
diskusage.exe -path 'd:/go; d:/Books'
并获取按照大小排列的文件夹列表
1.| DIR: d:/go | SIZE: 325.72 Mb | DEPTH: 1 2.| DIR: d:/Books | SIZE: 14.01 Mb | DEPTH: 1
此示例在HDD上执行时间为272ms。
您可以增加子文件夹的深度以进行分析,例如:
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:/Books/Chess | 大小: 14.01 Mb | 深度: 2 6.| 目录: d:/Books | 大小: 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 ***
我猜这只能在目录相对静态且其内容在两个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
@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
explorer C:\Users\%username%\AppData\Roaming\Microsoft\Windows\SendTo
这段代码已经经过测试。您可以再次检查它。
@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
dir 'FolderName'/s
- jeyko