Статистика папки PowerShell - PullRequest
       4

Статистика папки PowerShell

2 голосов
/ 21 февраля 2011

Я храню все модули нашей системы в одном каталоге (например, All\ModuleA; All\ModuleB). Я хочу посмотреть, какие типы файлов наиболее многочисленны и занимают больше места по модулям. Итак, я хотел бы вывод по линии:

ModName,java-count,java-size,xml-count,xml-size,png-count,png-size...
ModuleA,30,0.2,100,2.3,0,0,...
ModuleB,21,0.1,20,0.7,1,1.2

Не во всех модулях есть файлы всех типов, поэтому это будет работать, только если я перечислю все типы для всех модулей (с большим количеством нулей). У меня есть кое-что, что почти работает, но это отвратительно, многословно и неэффективно. Я уверен, что кто-то может помочь мне увидеть свет :-) (который, кстати, может быть частью бесплатного программного обеспечения, которое делает это из коробки; я решил сделать это только в PowerShell из интереса).

спасибо

Ответы [ 3 ]

4 голосов
/ 21 февраля 2011

Базовые командлеты group, select и sort должны сделать свое дело:

Get-ChildItem . | Where {!$_.PSIsContainer} | Group Extension | 
    Select Count, Name, @{n='Size';e={($_.Group | Measure Length -Sum).Sum}} | 
    Sort Size -desc | Format-Table -auto
1 голос
/ 22 февраля 2011

Я хотел бы увидеть ваше решение, потому что после очень короткого (неполного) решения я нашел

$dir = 'c:\windows\system32'
function Extension($item) {
    $e = $_.Extension.Trim('.')
    if ($e) { $e } else { '-empty-' }
}
# gets info about the folder
# returns 2 hashtables - one with sizes, one with counts (keys are extensions)
function GetInfo($dir) {
    $counts, $lengths = 
            gci $dir -rec | ? { !$_.PsIsContainer } | 
                % -begin { 
                     $c=@{}; $s=@{}} `
                  -process { 
                     $ext = Extension $_
                     $s[$ext] += $_.Length
                     $c[$ext] += 1 } `
                  -end {$c, $s}
    @{Counts = $counts; Lengths = $lengths }
}
# $res.Names holds all the property names (extensions) that will be used
# might be possible to use global variable, but...
$res = 
    gci $dir | 
    ? { $_.PsIsContainer } |
    % { new-object psobject -prop (@{Name=$_.Name} + (GetInfo $_.FullName)) } |
    % -beg { $names = @{}; $obj = @()}  `
      -process { $_.Lengths.Keys|%{ $names[$_] = $_ }
                 $obj += $_
               } `
      -end { @{Names=@($names.keys.GetEnumerator()); Dirs=$obj } }

# Create new objects from the partial info
$result = foreach ($dir in $res.Dirs) {
    $ret = New-Object PsObject -prop @{Name = $dir.Name}
    foreach ($name in $res.Names) {
        $ret | 
            # if there is no key in $dir.Counts or $dir.Lengths, 0 is returned
            Add-Member NoteProperty ($name+"_count") -value ([int]$dir.Counts[$name]) -pass |
            Add-Member NoteProperty ($name+"_size") -value ([int]$dir.Lengths[$name])
    }
    $ret
}

Код прокомментирован, поэтому должно быть понятно, что происходит.Сложной задачей было добавить свойства расширений для каждого объекта, даже если в каталоге нет файлов с расширением.(список расширений не является полным, пока он не пересекает все каталоги).

Тогда вы можете видеть, что результат является регулярным PsObject:

PS> $result | ft Name,dll_count,dll_size,exe_count,exe_size,bat_count,bat_size -auto
Name                   dll_count  dll_size exe_count exe_size bat_count bat_size
----                   ---------  -------- --------- -------- --------- --------
0409                           0         0         0        0         0        0
1033                           1     17760         0        0         0        0
AdvancedInstallers             3   2312192         0        0         0        0
ar-SA                          0         0         0        0         0        0
BestPractices                  0         0         0        0         0        0
bg-BG                          0         0         0        0         0        0
catroot                        0         0         0        0         0        0
catroot2                       0         0         0        0         0        0
com                            1    201216         2    24064         0        0
config                         0         0         0        0         0        0
0 голосов
/ 21 февраля 2011

Не уверен, что это менее "отвратительно, многословно и неэффективно", чем то, что вы используете, но вот как я подхожу к получению статистики по типам файлов в данной папке:

 $ext_count = @{}
 $ext_size = @{}
 gci c:\windows\system32 |
 where {-not $_.psiscontainer} |
  foreach-object {
   $ext_count[$_.extension] ++
   $ext_size[$_.extension] += [int]$_.length
   }

   $ext_count
   $ext_size

После этого нужно просто разобраться, кто вас интересует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...