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?
Utilisez un commutateur ou un ensemble d'énoncés "if". Votre logique (pseudocode) devrait ressembler à ceci:
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.
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)}
}
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]
}
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()
}
}
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
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
}
}
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