列出目录的名称和大小

问题描述 投票:2回答:2

我想列出具有全名,大小,LastWriteTime的目录,然后递归到第三级。

Get-ChildItem -Depth 3 |
    Where-Object {
        $_.PSIsContainer
        } |
    ForEach-Object {
        $_.FullName + ";" + "{0:N2}" -f ((Get-ChildItem $_ -Recurse |
            Measure-Object Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB) + " MB"+";"+ $_.LastWriteTime
        }

但是大小仅针对第一级目录进行测量。

输出为:

C:\folder1\folder2 ; 487,69 MB ; 30.01.2020 17:58:45
C:\folder1\folder2\folder3 ; 0,00 MB ; 30.01.2020 17:59:34
C:\folder1\folder2\folder3\folder4 ; 0,00 MB ; 30.01.2020 17:59:37

但是应该是这样,因为我在每个文件夹中都放置了相同的文件:

C:\folder1\folder2 ; 1463,07 MB ; 30.01.2020 17:58:45
C:\folder1\folder2\folder3 ; 975,38 MB ; 30.01.2020 17:59:34
C:\folder1\folder2\folder3\folder4 ; 487,69 MB ; 30.01.2020 17:59:37
powershell directory size get-childitem
2个回答
1
投票

这将输出目录的FullNameSizeLastWriteTime。请注意,如果size为空,则什么也不输出:

Get-ChildItem -Depth 3 | 
    Where-Object { $_.PSIsContainer} |
    foreach{
        $size = "{0:N2}" -f ((Get-ChildItem $_ -Recurse | 
            Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB)

        if ($size){
            Write-Host $_.FullName  ";"  $size "MB" ";" $_.LastWriteTime
        }
    }

让我们知道您的生活。

更新

更新您的问题后,请尝试以下代码:

Get-ChildItem -Depth 3 | 
    Where-Object { $_.PSIsContainer} |
    foreach{
        $folders = Get-ChildItem $_.FullName -Recurse

        [int]$totalSize = 0

        foreach ($folder in $folders){
            $totalSize += (Get-ItemProperty -Path $folder.FullName -Name Length -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Length)
        }

        if ($totalSize){
            Write-Host $_.FullName  ";"  $totalSize ";" $_.LastWriteTime
        }
    }

它可能可以清理,我只想看看它是否如您所愿:)


0
投票

您要做的是检查每个子目录的内容,并将其添加到其父目录中。然后,那个父母必须告诉它是超级父母,那个祖父母=>曾祖父母,等等。

每个文件都必须告知每个祖先它的大小,否则,例如,嵌套有30多个数据的目录将无法告诉C:驱动器它有多大。

这是一个递归问题,您可以通过在每个子代上调用该函数来实现,也可以创建一个队列并在到达每个子代时对其进行处理。

您还可以计算每个目录,然后使目录汇总其结果,也可以汇总每个文件。根据您是使用宽文件结构还是使用深文件结构,这可能会有所不同,但可以忽略不计。

我将此写为队列,每个文件都在报告。我认为,如果您突破了代码,则跟调用堆栈和最终汇总相比要容易一些。

function Get-DirSize {
    [CmdletBinding()]
    param (
        [Parameter(Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = "Directory path")]
        [ValidateNotNullOrEmpty()]
        $name = (Get-Item  ".")
    )
    $name = Get-Item $name
    $q = New-Object System.Collections.Queue
    $results = New-Object System.Collections.Queue
    $q.Enqueue([PSCustomObject]@{
            Parent    = $null
            Directory = $name
            Size      = 0
            Depth     = 0
        })
    do {
        $dir = $q.Dequeue()
        $results.Enqueue($dir)
        $children = $dir.Directory | Get-ChildItem
        foreach ($child in $children) {
            if ($child.PSIsContainer ) {
                $q.Enqueue([PSCustomObject]@{
                        Parent    = $dir
                        Directory = $child
                        Size      = 0
                        Depth     = $dir.Depth + 1
                    })
            }
            else {
                $tempDir = $dir
                while ($tempDir) {
                    $tempDir.Size += $child.length
                    $tempDir = $tempDir.Parent
                }
            }
        }
    } until ($q.Count -eq 0)
    $ret = $results | ForEach-Object {
        $dir = $_
        return [PSCustomObject]@{
            FullName      = $dir.Directory.FullName
            LastWriteTime = $dir.Directory.LastWriteTime
            Size          = $dir.Size
            Depth         = $dir.Depth
            PSDirObject   = $dir.Directory
        } 
    }
    return $ret
}

然后调用它,您可以传递您要检查的目录或当前工作目录:

Get-DirSize "c:\development" | Where-Object Depth -LE 3 | Select-Object FullName, LastWriteTime, @{n = "Size"; e = { "$($_.Size / 1MB)" + "MB" } }

输出必须按深度进行过滤,您可以使用自定义的select语句选择所需的列。

© www.soinside.com 2019 - 2024. All rights reserved.