我正在尝试列出光盘的文件夹结构和每个文件夹的大小。
我已经确定了文件夹结构,现在我只需要输出每个文件夹的大小即可。
根据https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/dir,没有用于显示文件大小的标志-仅将其隐藏。我猜我在这里走了错误的路线,但我们会提供任何帮助。
这是我到目前为止所得到的:
dir /s /b /o:n /a:d > "C:\folderlist.txt"
预期输出:
C:\WINDOWS\system32\downlevel 400mb
C:\WINDOWS\system32\drivers 100mb
C:\WINDOWS\system32\DriverState 4kb
C:\WINDOWS\system32\DriverStore 1kb
C:\WINDOWS\system32\DRVSTORE 1gb
文件大小的首字母缩写,即(mb,kb,gb,tb)无关紧要。只要它以某种可量化的方式显示出文件夹的大小即可。
也欢迎使用Powershell替代方案。
答案 0 :(得分:2)
使用dir
无法获得文件夹大小。您需要递归计算每个文件夹的大小。有许多有效的Powershell示例。这个非常不错https://md3v.com/getting-a-folder-tree-size-with-powershell:
function tree($startFolder)
{
$colItems = Get-ChildItem $startFolder | Where-Object {$_.PSIsContainer -eq $true} | Sort-Object
foreach ($i in $colItems)
{
$subFolderItems = Get-ChildItem $i.FullName -recurse -force | Where-Object {$_.PSIsContainer -eq $false} | Measure-Object -property Length -sum | Select-Object Sum
$i.FullName + " -- " + "{0:N2}" -f ($subFolderItems.sum / 1MB) + " MB"
tree $i.FullName
}
}
答案 1 :(得分:1)
基于montonero's helpful answer的 PowerShell解决方案,并改进了以下方面:
基于以下定义的函数Get-DirectorySize
的示例调用:
# Get the size of the current directory (only).
Get-DirectorySize
# As requested by the OP:
# Recursively report the sizes of all subdirectories in the current directory.
Get-DirectorySize -Recurse -ExcludeSelf
# Get the size of all child directories and sort them by size, from largest
# to smallest, showing only the 5 largest ones:
Get-DirectorySize -Depth 1 -ExcludeSelf |
Sort-Object Size -Descending |
Select-Object -First 5
上一条命令的输出示例:
FullName FriendlySize Size
-------- ------------ ----
C:\Users\jdoe\AppData 3.27gb 3514782772
C:\Users\jdoe\Desktop 801.40mb 840326199
C:\Users\jdoe\.nuget 778.97mb 816814396
C:\Users\jdoe\.vscode 449.12mb 470931418
C:\Users\jdoe\Projects 104.07mb 109127742
请注意,属性.FriendlySize
包含大小友好的,自动缩放的 string 表示形式,而.Size
是包含实际大小的数字([long]
)字节数,这有助于进一步的编程过程。
注意:仅在实现方便的情况下,在此处将属性添加到输出对象中仅有助于友好显示。正确的Powershell方法将是根据输出对象类型定义格式说明,请参见the docs。
注意事项(也适用于链接的答案):
仅报告逻辑的大小,即文件 data 所需的实际字节,与磁盘上的大小不同>,通常为更大,这是因为文件占据了固定大小的块;相反,压缩文件和稀疏文件占用的磁盘空间少于 。
使用-Recurse
和/或-Depth
进行递归的实现效率低下,因为遇到的每个目录的子树都被完全扫描了;文件系统缓存对此有所帮助。
Get-DirectorySize
源代码注意:需要Windows PowerShell v3 +;请参见还与PowerShell Core 兼容。
function Get-DirectorySize
{
param(
[Parameter(ValueFromPipeline)] [Alias('PSPath')]
[string] $LiteralPath = '.',
[switch] $Recurse,
[switch] $ExcludeSelf,
[int] $Depth = -1,
[int] $__ThisDepth = 0 # internal use only
)
process {
# Resolve to a full filesystem path, if necessary
$fullName = if ($__ThisDepth) { $LiteralPath } else { Convert-Path -ErrorAction Stop -LiteralPath $LiteralPath }
if ($ExcludeSelf) { # Exclude the input dir. itself; implies -Recurse
$Recurse = $True
$ExcludeSelf = $False
} else { # Process this dir.
# Calculate this dir's total logical size.
# Note: [System.IO.DirectoryInfo].EnumerateFiles() would be faster,
# but cannot handle inaccessible directories.
$size = [Linq.Enumerable]::Sum(
[long[]] (Get-ChildItem -Force -Recurse -File -LiteralPath $fullName).ForEach('Length')
)
# Create a friendly representation of the size.
$decimalPlaces = 2
$padWidth = 8
$scaledSize = switch ([double] $size) {
{$_ -ge 1tb } { $_ / 1tb; $suffix='tb'; break }
{$_ -ge 1gb } { $_ / 1gb; $suffix='gb'; break }
{$_ -ge 1mb } { $_ / 1mb; $suffix='mb'; break }
{$_ -ge 1kb } { $_ / 1kb; $suffix='kb'; break }
default { $_; $suffix='b'; $decimalPlaces = 0; break }
}
# Construct and output an object representing the dir. at hand.
[pscustomobject] @{
FullName = $fullName
FriendlySize = ("{0:N${decimalPlaces}}${suffix}" -f $scaledSize).PadLeft($padWidth, ' ')
Size = $size
}
}
# Recurse, if requested.
if ($Recurse -or $Depth -ge 1) {
if ($Depth -lt 0 -or (++$__ThisDepth) -le $Depth) {
# Note: This top-down recursion is inefficient, because any given directory's
# subtree is processed in full.
Get-ChildItem -Force -Directory -LiteralPath $fullName |
ForEach-Object { Get-DirectorySize -LiteralPath $_.FullName -Recurse -Depth $Depth -__ThisDepth $__ThisDepth }
}
}
}
}
这是该功能的基于注释的帮助;如果您将功能添加到您的$PROFILE
中,则将帮助直接放在功能上方或功能内部,以获得对-?
的支持并与Get-Help
自动集成。
<#
.SYNOPSIS
Gets the logical size of directories in bytes.
.DESCRIPTION
Given a literal directory path, output that directory's logical size, i.e.,
the sum of all files contained in the directory, including hidden ones.
NOTE:
* The logical size is distinct from the size on disk, given that files
are stored in fixed-size blocks. Furthermore, files can be compressed
or sparse.
Thus, the size of regular files on disk is typically greater than
their logical size; conversely, compressed and sparse files require less
disk space.
Finally, the list of child items maintained by the filesystem for each
directory requires disk space too.
* Wildcard expressions aren't directly supported, but you may pipe in
Output from Get-ChildItem / Get-Item; if files rather than directotries
happen to be among the input objects, their size is reported as-is.
CAVEATS:
* Can take a long time to run with large directory trees, especially with
-Recurse.
* Recursion is implemented inefficently.
.PARAMETER LiteralPath
The literal path of a directory. May be provided via the pipeline.
.PARAMETER Recurse
Calculates the logical size not only of the input directory itself, but of
all subdirectories in its subtree too.
To limit the recursion depth, use -Depth.
.PARAMETER Depth
Limits the recursion depth to the specified number of levels. Implies -Recurse.
Note that 0 means no recursion. Use just -Recurse in order not to limit the
recursion.
.PARAMETER ExcludeSelf
Excludes the target directory itself from the size calculation.
Implies -Recurse. Since -Depth implies -Recurse, you could use -ExcludeSelf
-Depth 1 to report only the sizes of the immediate subdirectories.
.OUTPUTS
[pscustomobject] instances with properties FullName, Size, and FriendlySize.
.EXAMPLE
Get-DirectorySize
Gets the logical size of the current directory.
.EXAMPLE
Get-DirectorySize -Recurse
Gets the logical size of the current directory and all its subdirectories.
.EXAMPLE
Get-DirectorySize /path/to -ExcludeSelf -Depth 1 | Sort-Object Size
Gets the logical size of all child directories in /path/to without including
/path/to itself, and sorts the result by size (largest last).
#>
答案 2 :(得分:0)
这是一个批处理脚本,其中列出了给定根目录中的所有目录及其大小。提供根目录作为第一个命令行参数;如果省略,则使用当前目录。这是代码:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=%~1" & if not defined _ROOT set "_ROOT=."
rem // Change into the given root directory:
pushd "%_ROOT%" && (
rem // Walk through all immediate sub-directories:
for /F "delims= eol=|" %%D in ('dir /B /A:D-H "*"') do (
rem // Initialise variable holding size of sub-directory:
set "SIZE=0"
rem // Process sub-directory in a sub-soutine:
set "ITEM=%%~D" & call :PROCESS SIZE "%%ITEM%%"
rem // Display size of sub-directory:
call set "SIZE= %%SIZE%%"
set "ITEM=%%~fD" & call echo %%SIZE:~-14%% "%%ITEM%%"
)
popd
)
endlocal
exit /B
:PROCESS
rem /* Change into the given directory; use short names to avoid trouble with
rem extremely long and/or deep paths (remember the limit is 260 characters): */
pushd "%~s2" && (
rem /* Walk through all files in the directory; instead of a normal `for` loop,
rem `dir` together with a `for /F` loop is used, because `for` would ignore
rem hidden files; with `dir` you can choose the attributes and therefore
rem ensure that all files are returned: */
for /F "delims= eol=|" %%F in ('2^> nul dir /B /A:-D "*"') do (
rem // Sum up the file sizes in a sub-routine:
call :SUM SIZE "%%SIZE%%" "%%~zF"
)
rem /* Walk through all sub-directories; instead of a normal `for` loop, `dir`
rem together with a `for /F` loop is used, because `for` would ignore hidden
rem sub-directories; with `dir` you can choose the attributes and therefore
rem ensure that all sub-directories are returned: */
for /F "delims= eol=|" %%D in ('2^> nul dir /B /A:D "*"') do (
rem // Call this sub-routine recursively to process sub-directories:
set "ITEM=%%~D" & call :PROCESS SIZE "%%ITEM%%"
)
popd
)
rem // Return resulting directory size:
set "%~1=%SIZE%"
exit /B
:SUM
rem // Split provided numbers into ones and billions:
set "ENA1=%~2" & set "ENA2=%~3"
set "GIG1=%ENA1:~,-9%" & set "ENA1=%ENA1:~-9%"
set "GIG2=%ENA2:~,-9%" & set "ENA2=%ENA2:~-9%"
rem /* Sum up the ones, disregard leading zeros, which would let numbers be
rem interpreted as octal ones: */
for /F "tokens=* delims=0" %%M in ("0%ENA1%") do (
for /F "tokens=* delims=0" %%N in ("0%ENA2%") do (
set /A "ENA=%%M+%%N+0"
)
)
rem // Sum up the billions, regard the carry from the ones:
set "GIG=%ENA:~,-9%" & set /A "GIG1+=0, GIG2+=0, GIG+=GIG1+GIG2"
rem // Join resulting billions and ones to the finally resulting number:
set "ENA=000000000%ENA%"
for /F "tokens=* delims=0" %%K in ("%GIG%%ENA:~-9%") do set "%~1=%%K"
exit /B
示例调用(假设脚本名为list_folders.bat
)
list_folders.bat "D:\Root"
示例输出:
442368 "D:\Root\Data" 101685022 "D:\Root\More" 5441536 "D:\Root\Test"