你在 PowerShell 中吗?

发布于 2024-07-21 04:49:17 字数 293 浏览 6 评论 0原文

如何使用 PowerShell 获得 du 式分析? 我想定期检查磁盘上目录的大小。

以下给出了当前目录中每个文件的大小:

foreach ($o in gci)
{
   Write-output $o.Length
}

但我真正想要的是目录中所有文件(包括子目录)的总大小。 另外,我希望能够根据大小对其进行排序(可选)。

How can I get a du-ish analysis using PowerShell? I'd like to periodically check the size of directories on my disk.

The following gives me the size of each file in the current directory:

foreach ($o in gci)
{
   Write-output $o.Length
}

But what I really want is the aggregate size of all files in the directory, including subdirectories. Also I'd like to be able to sort it by size, optionally.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

清旖 2024-07-28 04:49:17

“探索美丽的语言”博客中有一个实现:

“Powershell 中“du -s *”的实现”

function directory-summary($dir=".") { 
  get-childitem $dir | 
    % { $f = $_ ; 
        get-childitem -r $_.FullName | 
           measure-object -property length -sum | 
             select @{Name="Name";Expression={$f}},Sum}
}

(博客所有者的代码:Luis Diego Fallas)

输出:

PS C:\Python25> directory-summary

Name                  Sum
----                  ---
DLLs              4794012
Doc               4160038
include            382592
Lib              13752327
libs               948600
tcl               3248808
Tools              547784
LICENSE.txt         13817
NEWS.txt            88573
python.exe          24064
pythonw.exe         24576
README.txt          56691
w9xpopen.exe         4608

There is an implementation available at the "Exploring Beautiful Languages" blog:

"An implementation of 'du -s *' in Powershell"

function directory-summary($dir=".") { 
  get-childitem $dir | 
    % { $f = $_ ; 
        get-childitem -r $_.FullName | 
           measure-object -property length -sum | 
             select @{Name="Name";Expression={$f}},Sum}
}

(Code by the blog owner: Luis Diego Fallas)

Output:

PS C:\Python25> directory-summary

Name                  Sum
----                  ---
DLLs              4794012
Doc               4160038
include            382592
Lib              13752327
libs               948600
tcl               3248808
Tools              547784
LICENSE.txt         13817
NEWS.txt            88573
python.exe          24064
pythonw.exe         24576
README.txt          56691
w9xpopen.exe         4608
望她远 2024-07-28 04:49:17

我稍微修改了答案中的命令,以按大小降序排序,并包含以 MB 为单位的大小:

gci . | 
  %{$f=$_; gci -r $_.FullName | 
    measure-object -property length -sum |
    select  @{Name="Name"; Expression={$f}}, 
            @{Name="Sum (MB)"; 
            Expression={"{0:N3}" -f ($_.sum / 1MB) }}, Sum } |
  sort Sum -desc |
  format-table -Property Name,"Sum (MB)", Sum -autosize

输出:

PS C:\scripts> du

Name                                 Sum (MB)       Sum
----                                 --------       ---
results                              101.297  106217913
SysinternalsSuite                    56.081    58805079
ALUC                                 25.473    26710018
dir                                  11.812    12385690
dir2                                 3.168      3322298

也许这不是最有效的方法,但它有效。

I modified the command in the answer slightly to sort descending by size and include size in MB:

gci . | 
  %{$f=$_; gci -r $_.FullName | 
    measure-object -property length -sum |
    select  @{Name="Name"; Expression={$f}}, 
            @{Name="Sum (MB)"; 
            Expression={"{0:N3}" -f ($_.sum / 1MB) }}, Sum } |
  sort Sum -desc |
  format-table -Property Name,"Sum (MB)", Sum -autosize

Output:

PS C:\scripts> du

Name                                 Sum (MB)       Sum
----                                 --------       ---
results                              101.297  106217913
SysinternalsSuite                    56.081    58805079
ALUC                                 25.473    26710018
dir                                  11.812    12385690
dir2                                 3.168      3322298

Maybe it is not the most efficient method, but it works.

回忆躺在深渊里 2024-07-28 04:49:17

如果您只需要该路径的总大小,可以使用一个简化版本,

Get-ChildItem -Recurse ${HERE_YOUR_PATH} | Measure-Object -Sum Length

If you only need the total size of that path, one simplified version can be,

Get-ChildItem -Recurse ${HERE_YOUR_PATH} | Measure-Object -Sum Length
心作怪 2024-07-28 04:49:17
function Get-DiskUsage ([string]$path=".") {
    $groupedList = Get-ChildItem -Recurse -File $path | Group-Object directoryName | select name,@{name='length'; expression={($_.group | Measure-Object -sum length).sum } }
    foreach ($dn in $groupedList) {
        New-Object psobject -Property @{ directoryName=$dn.name; length=($groupedList | where { $_.name -like "$($dn.name)*" } | Measure-Object -Sum length).sum }
    }
}

我的有点不同; 我将目录名上的所有文件分组,然后遍历每个目录的构建总数列表(包括子目录)。

function Get-DiskUsage ([string]$path=".") {
    $groupedList = Get-ChildItem -Recurse -File $path | Group-Object directoryName | select name,@{name='length'; expression={($_.group | Measure-Object -sum length).sum } }
    foreach ($dn in $groupedList) {
        New-Object psobject -Property @{ directoryName=$dn.name; length=($groupedList | where { $_.name -like "$($dn.name)*" } | Measure-Object -Sum length).sum }
    }
}

Mine is a bit different; I group all of the files on directoryname, then walk through that list building totals for each directory (to include the subdirectories).

や三分注定 2024-07-28 04:49:17

基于之前的答案,这适用于那些想要以 KB、MB、GB 等显示大小,并且仍然能够按大小排序的人。 要更改单位,只需将“Name=”和“Expression=”中的“MB”更改为所需单位即可。 您还可以通过更改“2”来更改要显示的小数位数(四舍五入)。

function du($path=".") {
    Get-ChildItem $path |
    ForEach-Object {
        $file = $_
        Get-ChildItem -File -Recurse $_.FullName | Measure-Object -Property length -Sum |
        Select-Object -Property @{Name="Name";Expression={$file}},
                                @{Name="Size(MB)";Expression={[math]::round(($_.Sum / 1MB),2)}} # round 2 decimal places
    }
}

这将大小作为数字而不是字符串(如另一个答案中所示)提供,因此可以按大小排序。 例如:

PS C:\Users\merce> du | Sort-Object -Property "Size(MB)" -Descending

Name      Size(MB)
----      --------
OneDrive  30944.04
Downloads    401.7
Desktop     335.07
.vscode     301.02
Intel         6.62
Pictures      6.36
Music         0.06
Favorites     0.02
.ssh          0.01
Searches         0
Links            0

Building on previous answers, this will work for those that want to show sizes in KB, MB, GB, etc., and still be able to sort by size. To change units, just change "MB" to desired units in both "Name=" and "Expression=". You can also change the number of decimal places to show (rounding), by changing the "2".

function du($path=".") {
    Get-ChildItem $path |
    ForEach-Object {
        $file = $_
        Get-ChildItem -File -Recurse $_.FullName | Measure-Object -Property length -Sum |
        Select-Object -Property @{Name="Name";Expression={$file}},
                                @{Name="Size(MB)";Expression={[math]::round(($_.Sum / 1MB),2)}} # round 2 decimal places
    }
}

This gives the size as a number not a string (as seen in another answer), therefore one can sort by size. For example:

PS C:\Users\merce> du | Sort-Object -Property "Size(MB)" -Descending

Name      Size(MB)
----      --------
OneDrive  30944.04
Downloads    401.7
Desktop     335.07
.vscode     301.02
Intel         6.62
Pictures      6.36
Music         0.06
Favorites     0.02
.ssh          0.01
Searches         0
Links            0
俯瞰星空 2024-07-28 04:49:17
Here is a simple recursive powershell script that does the job.
It is not as slick as the sysinternals du and in my example it is showing directories in C:\Program Files that have more than 200 MB in them.

Function List-DiskUsage {
    Param ($Path= '.\')
           

 if ($FirstTime ) {  
                     $lvl=0
                     $FirstTime = $false
     }
    $ar[$lvl].WholePath=$Path

    Get-ChildItem -Path $Path -Force -ErrorAction  SilentlyContinue| ForEach-Object {
       
        If (! $_.PSIsContainer ) {
          $len = [math]::Round($_.Length/1MB,2)
          $ar[$lvl].AccumSize+=$len
#          write-host    $lvl "   File          "  $_.Name   "      "   $len  "      " $_.FullName
         
        } ElseIf ($_.PSIsContainer) {
            $ar[$lvl].NumSubDirs+=1
            $lvl+=1
#write-host  $lvl "  Directory         "     $_.Name   "       "   $_.Length  "      " $_.FullName
            List-DiskUsage($Path=$_.FullName)
            $lvl-=1
  if ($ar[$lvl+1].AccumSize -gt 200 ) {
       $newlen=[math]::Round($ar[$lvl+1].AccumSize,0)

       Write-host  $newlen "`tMB     "  $ar[$lvl+1].WholePath  " Dirs= " $ar[$lvl+1].NumSubDirs 
  } 

#           add this level totals into next higher level.

            $ar[$lvl].AccumSize+=$ar[$lvl+1].AccumSize
            $ar[$lvl+1].AccumSize=0
            $ar[$lvl+1].WholePath=""
            $ar[$lvl+1].NumSubdirs=0
        } # End If-ElseIf.
    } # End ForEach-Object.
if ($lvl -eq 0 ) {
       $newlen=[math]::Round($ar[0].AccumSize,0)
       Write-host  $newlen "`tMB     "  $ar[0].WholePath  " Dirs= " $ar[0].NumSubDirs 
    }

} # End Function: List-DiskUsage.




$Global:FirstTime="True"
$Global:lvl=0

$Global:ar = @(
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
 )

List-DiskUsage("C:\Program Files")

    
Here is a simple recursive powershell script that does the job.
It is not as slick as the sysinternals du and in my example it is showing directories in C:\Program Files that have more than 200 MB in them.

Function List-DiskUsage {
    Param ($Path= '.\')
           

 if ($FirstTime ) {  
                     $lvl=0
                     $FirstTime = $false
     }
    $ar[$lvl].WholePath=$Path

    Get-ChildItem -Path $Path -Force -ErrorAction  SilentlyContinue| ForEach-Object {
       
        If (! $_.PSIsContainer ) {
          $len = [math]::Round($_.Length/1MB,2)
          $ar[$lvl].AccumSize+=$len
#          write-host    $lvl "   File          "  $_.Name   "      "   $len  "      " $_.FullName
         
        } ElseIf ($_.PSIsContainer) {
            $ar[$lvl].NumSubDirs+=1
            $lvl+=1
#write-host  $lvl "  Directory         "     $_.Name   "       "   $_.Length  "      " $_.FullName
            List-DiskUsage($Path=$_.FullName)
            $lvl-=1
  if ($ar[$lvl+1].AccumSize -gt 200 ) {
       $newlen=[math]::Round($ar[$lvl+1].AccumSize,0)

       Write-host  $newlen "`tMB     "  $ar[$lvl+1].WholePath  " Dirs= " $ar[$lvl+1].NumSubDirs 
  } 

#           add this level totals into next higher level.

            $ar[$lvl].AccumSize+=$ar[$lvl+1].AccumSize
            $ar[$lvl+1].AccumSize=0
            $ar[$lvl+1].WholePath=""
            $ar[$lvl+1].NumSubdirs=0
        } # End If-ElseIf.
    } # End ForEach-Object.
if ($lvl -eq 0 ) {
       $newlen=[math]::Round($ar[0].AccumSize,0)
       Write-host  $newlen "`tMB     "  $ar[0].WholePath  " Dirs= " $ar[0].NumSubDirs 
    }

} # End Function: List-DiskUsage.




$Global:FirstTime="True"
$Global:lvl=0

$Global:ar = @(
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
    [pscustomobject]@{WholePath='';AccumSize=0;NumSubDirs=0}
 )

List-DiskUsage("C:\Program Files")

    
怪我闹别瞎闹 2024-07-28 04:49:17

我自己使用之前的答案的看法:

function Format-FileSize([int64] $size) {
    if ($size -lt 1024)
    {
        return $size
    }
    if ($size -lt 1Mb)
    {
        return "{0:0.0} Kb" -f ($size/1Kb)
    }
    if ($size -lt 1Gb)
    {
        return "{0:0.0} Mb" -f ($size/1Mb)
    }
    return "{0:0.0} Gb" -f ($size/1Gb)
}

function du {
        param(
        [System.String]
        $Path=".",
        [switch]
        $SortBySize,
        [switch]
        $Summary
    )
    $path = (get-item ".").FullName
    $groupedList = Get-ChildItem -Recurse -File $Path | 
        Group-Object directoryName | 
            select name,@{name='length'; expression={($_.group | Measure-Object -sum length).sum } }
    $results = ($groupedList | % {
        $dn = $_
        if ($summary -and ($path -ne $dn.name)) {
            return
        }
        $size = ($groupedList | where { $_.name -like "$($dn.name)*" } | Measure-Object -Sum length).sum
        New-Object psobject -Property @{ 
            Directory=$dn.name; 
            Size=Format-FileSize($size);
            Bytes=$size` 
        }
    })
    if ($SortBySize)
        { $results = $results | sort-object -property Bytes }
    $results | more
}

My own take using the previous answers:

function Format-FileSize([int64] $size) {
    if ($size -lt 1024)
    {
        return $size
    }
    if ($size -lt 1Mb)
    {
        return "{0:0.0} Kb" -f ($size/1Kb)
    }
    if ($size -lt 1Gb)
    {
        return "{0:0.0} Mb" -f ($size/1Mb)
    }
    return "{0:0.0} Gb" -f ($size/1Gb)
}

function du {
        param(
        [System.String]
        $Path=".",
        [switch]
        $SortBySize,
        [switch]
        $Summary
    )
    $path = (get-item ".").FullName
    $groupedList = Get-ChildItem -Recurse -File $Path | 
        Group-Object directoryName | 
            select name,@{name='length'; expression={($_.group | Measure-Object -sum length).sum } }
    $results = ($groupedList | % {
        $dn = $_
        if ($summary -and ($path -ne $dn.name)) {
            return
        }
        $size = ($groupedList | where { $_.name -like "$($dn.name)*" } | Measure-Object -Sum length).sum
        New-Object psobject -Property @{ 
            Directory=$dn.name; 
            Size=Format-FileSize($size);
            Bytes=$size` 
        }
    })
    if ($SortBySize)
        { $results = $results | sort-object -property Bytes }
    $results | more
}
彻夜缠绵 2024-07-28 04:49:17

使用 Get-Chiltree 并没有那么慢:

(Get-ChildItem -Path $path -Recurse | Measure-Object -Property Length -Sum).Sum / 1GB

Using Get-Chiltree, is not that slow :

(Get-ChildItem -Path $path -Recurse | Measure-Object -Property Length -Sum).Sum / 1GB
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文