programing

du in PowerShell?

batch 2023. 8. 19. 09:58
반응형

du in PowerShell?

PowerShell을 사용하여 듀이쉬 분석을 수행하려면 어떻게 해야 합니까?디스크의 디렉터리 크기를 주기적으로 확인하려고 합니다.

다음은 현재 디렉터리에 있는 각 파일의 크기를 보여 줍니다.

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

하지만 제가 정말 원하는 것은 하위 디렉터리를 포함하여 디렉터리에 있는 모든 파일의 총 크기입니다.또한 선택적으로 크기별로 분류할 수 있으면 좋겠습니다.

"아름다운 언어 탐색" 블로그에서 사용할 수 있는 구현이 있습니다.

"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}
}

(블로그 소유자 코드:루이스 디에고 팔라스)

출력:

PSC:\Python25> 디렉토리 요약
이름 합계----                  ---DLL 4794012문서 4160038382592 포함Lib 13752327libs 948600tcl 3248808도구 547784라이센스.txt 13817NEWS.txt 88573python.exe 24064pythonw.exe 24576README.txt 56691w9xpopen.exe 4608

크기별로 내림차순으로 정렬하고 크기를 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

가장 효율적인 방법은 아닐 수도 있지만 효과가 있습니다.

해당 경로의 전체 크기만 필요한 경우 단순화된 버전은 다음과 같습니다.

Get-ChildItem -Recurse ${HERE_YOUR_PATH} | Measure-Object -Sum Length
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 }
    }
}

제 것은 조금 다릅니다. 저는 디렉토리 이름에 있는 모든 파일을 그룹화한 다음 각 디렉토리(하위 디렉토리 포함)에 대한 전체 목록을 살펴봅니다.

이전 답변을 바탕으로 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
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")

    

이전 답변을 사용한 나만의 의견:

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
}

Get-Chiltree를 사용하는 것은 그리 느리지 않습니다.

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

언급URL : https://stackoverflow.com/questions/868264/du-in-powershell

반응형