web-dev-qa-db-fra.com

Taille des fichiers d’affichage PowerShell exprimée en Ko, Mo ou Go

J'ai une section d'un script PowerShell qui obtient la taille du fichier d'un répertoire spécifié.

Je peux obtenir les valeurs de différentes unités de mesure sous forme de variables, mais je ne connais pas le bon moyen d’afficher celle qui convient.

$DirSize = "{0:N2}" -f (($DirArray | Measure-Object -property length -sum).sum)
$DirSizeKB = "{0:N2}" -f (($DirArray | Measure-Object -property length -sum).sum / 1KB)
$DirSizeMB = "{0:N2}" -f (($DirArray | Measure-Object -property length -sum).sum / 1MB)
$DirSizeGB = "{0:N2}" -f (($DirArray | Measure-Object -property length -sum).sum / 1GB)

Si le nombre d'octets est d'au moins 1 Ko, je veux que la valeur en Ko soit affichée. Si le nombre de Ko est d'au moins 1 Mo, je veux afficher les Mo, etc.

Y a-t-il un bon moyen d'accomplir cela?

8
Beninja2

Utilisez un commutateur ou un ensemble d'énoncés "if". Votre logique (pseudocode) devrait ressembler à ceci:

  1. La taille est-elle d'au moins 1 Go? Oui, affichage en Go (sinon ...)
  2. La taille est-elle d'au moins 1 Mo? Oui, affichage en Mo (sinon ...)
  3. Afficher en ko.

Notez que vous devriez tester dans l'ordre inverse, de la plus grande taille à la plus petite. Oui, j'aurais pu écrire le code pour vous, mais je suppose que vous en savez suffisamment pour transformer ce qui précède en un script fonctionnel. C'est juste l'approche qui t'avait stumped.

3
x0n

Il y a plusieurs manières de faire ça. En voici un:

switch -Regex ([math]::truncate([math]::log($bytecount,1024))) {

    '^0' {"$bytecount Bytes"}

    '^1' {"{0:n2} KB" -f ($bytecount / 1KB)}

    '^2' {"{0:n2} MB" -f ($bytecount / 1MB)}

    '^3' {"{0:n2} GB" -f ($bytecount / 1GB)}

    '^4' {"{0:n2} TB" -f ($bytecount / 1TB)}

     Default {"{0:n2} PB" -f ($bytecount / 1pb)}
}
10
mjolinor

Le mien est similaire à celui de @zdan mais écrit en tant que fonction de script:

function DisplayInBytes($num) 
{
    $suffix = "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
    $index = 0
    while ($num -gt 1kb) 
    {
        $num = $num / 1kb
        $index++
    } 

    "{0:N1} {1}" -f $num, $suffix[$index]
}
7
Mladen Mihajlovic

Voici une fonction que j'ai écrite il y a longtemps et qui utilise l'API Win32 pour accomplir ce que vous cherchez.

Function Convert-Size {
    <#
        .SYSNOPSIS
            Converts a size in bytes to its upper most value.

        .DESCRIPTION
            Converts a size in bytes to its upper most value.

        .PARAMETER Size
            The size in bytes to convert

        .NOTES
            Author: Boe Prox
            Date Created: 22AUG2012

        .EXAMPLE
        Convert-Size -Size 568956
        555 KB

        Description
        -----------
        Converts the byte value 568956 to upper most value of 555 KB

        .EXAMPLE
        Get-ChildItem  | ? {! $_.PSIsContainer} | Select -First 5 | Select Name, @{L='Size';E={$_ | Convert-Size}}
        Name                                                           Size                                                          
        ----                                                           ----                                                          
        Data1.cap                                                      14.4 MB                                                       
        Data2.cap                                                      12.5 MB                                                       
        Image.iso                                                      5.72 GB                                                       
        Index.txt                                                      23.9 KB                                                       
        SomeSite.lnk                                                   1.52 KB     
        SomeFile.ini                                                   152 bytes   

        Description
        -----------
        Used with Get-ChildItem and custom formatting with Select-Object to list the uppermost size.          
    #>
    [cmdletbinding()]
    Param (
        [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [Alias("Length")]
        [int64]$Size
    )
    Begin {
        If (-Not $ConvertSize) {
            Write-Verbose ("Creating signature from Win32API")
            $Signature =  @"
                 [DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
                 public static extern long StrFormatByteSize( long fileSize, System.Text.StringBuilder buffer, int bufferSize );
"@
            $Global:ConvertSize = Add-Type -Name SizeConverter -MemberDefinition $Signature -PassThru
        }
        Write-Verbose ("Building buffer for string")
        $stringBuilder = New-Object Text.StringBuilder 1024
    }
    Process {
        Write-Verbose ("Converting {0} to upper most size" -f $Size)
        $ConvertSize::StrFormatByteSize( $Size, $stringBuilder, $stringBuilder.Capacity ) | Out-Null
        $stringBuilder.ToString()
    }
}
4
boeprox

J'espère que le code suivant vous aidera ...

$file = 'C:\file.txt'
Write-Host((Get-Item $file).length/1KB) // returns file length in KB
Write-Host((Get-Item $file).length/1MB) // returns file length in MB
Write-Host((Get-Item $file).length/1GB) // returns file length in GB
4
Nandha kumar

J'ai ajouté la fonction DisplayInBytes ($ num) dans le script Bill Stewart "d.ps1"

function DisplayInBytes($num)
{
    $suffix = "oct", "Kib", "Mib", "Gib", "Tib", "Pib", "Eib", "Zib", "Yib"
    $index = 0
    while ($num -gt 1kb) 
    {
        $num = $num / 1kb
        $index++
    }

    $sFmt="{0:N"
    if ($index -eq 0) {$sFmt += "0"} else {$sFmt += "1"}
    $sFmt += "} {1}"
    $sFmt -f $num, $suffix[$index]
}

Remplacer le bloc

  # Create the formatted string expression.
   $formatStr = "`"{0,5} {1,10} {2,5} {3,15:N0} ({4,11})"   $formatStr += iif { -not $Q } { " {5}" } { " {5,-22} {6}" }   $formatStr += "`" -f `$_.Mode," +
        "`$_.$TimeField.ToString('d')," +
        "`$_.$TimeField.ToString('t')," +
        "`$_.Length,`$sfSize"

Et

  if (-not $Bare) {
    $sfSize=DisplayInBytes $_.Length
    invoke-expression $formatStr

Et à la fin

  # Output footer information when not using -bare.
  if (-not $Bare) {
    if (($fileCount -gt 0) -or ($dirCount -gt 0)) {
      $sfSize = DisplayInBytes $sizeTotal
      "{0,14:N0} file(s) {1,15:N0} ({3,11})`n{2,15:N0} dir(s)" -f
        $fileCount,$sizeTotal,$dirCount,$sfSize
    }
  }
0
PcSi-L

Une alternative à un groupe de if/commutateurs consiste à utiliser une boucle while jusqu'à ce que votre valeur ait la bonne taille. Ça pèse!

[double] $val = ($DirArray | Measure-Object -property length -sum).sum
while($val -gt 1kb){$val /= 1kb;}
"{0:N2}" -f $val
0
zdan