【问题标题】:How to convert value to KB, MB, or GB depending on digit placeholders?如何根据数字占位符将值转换为 KB、MB 或 GB?
【发布时间】:2019-08-16 19:48:41
【问题描述】:

我有以下

Import-Module SqlServer

$Analysis_Server = New-Object Microsoft.AnalysisServices.Server  
$Analysis_Server.connect("$server")

$estimatedSize = $([math]::Round($($($Analysis_Server.Databases[$cube].EstimatedSize)/1024/1024),2))

这会为我生成以 MB 为单位的大小

我想对其进行增强,使其更易于用户阅读,尤其是对于两位数 MB 中的值

例如,有时我会得到值50.9 MB,这很好。但其他一些值是37091 MB3082.86 MB,如果它们在GB 范围内,我希望它们自动转换为GB(分别为37.09 GB, 3.08 GB)。

如果有不在 MB 范围内的值,它们应该以 KB 显示

0.78 MB 应该只是 780 KB

我怎样才能做到这一点?

【问题讨论】:

    标签: powershell ssas


    【解决方案1】:

    抛开KB: 1024 vs 1000 的讨论,我们should 使用KiB,但没有人这样做,包括Microsoft(PowerShell、Explorer 等):

    PS C:\> 1Kb
    1024
    

    使用The Windows Shell shlwapi.h StrFormatByteSize 函数:

    $Shlwapi = Add-Type -MemberDefinition '
        [DllImport("Shlwapi.dll", CharSet=CharSet.Auto)]public static extern int StrFormatByteSize(long fileSize, System.Text.StringBuilder pwszBuff, int cchBuff);
    ' -Name "ShlwapiFunctions" -namespace ShlwapiFunctions -PassThru
    
    Function Format-ByteSize([Long]$Size) {
        $Bytes = New-Object Text.StringBuilder 20
        $Return = $Shlwapi::StrFormatByteSize($Size, $Bytes, $Bytes.Capacity)
        If ($Return) {$Bytes.ToString()}
    }
    

    示例:

    PS C:\> Format-ByteSize 37091MB
    36.2 GB
    PS C:\> Format-ByteSize 3082.86MB
    3.00 GB
    PS C:\> Format-ByteSize 0.78MB
    798 KB
    PS C:\> Format-ByteSize 670
    670 bytes
    

    【讨论】:

    • 有趣!你能解释一下这部分吗? $Bytes = New-Object Text.StringBuilder 20 20 是做什么的?另外,我知道在我的帖子中我说 MB 到 KB 或 GB(或 GiB/KiB,因为这更正确),但是您的函数适用于以字节为单位的起始大小是否正确?换句话说,我应该得到默认的字节大小: 得到这个函数的字节大小$Size = $Analysis_Server.Databases[$cube].EstimatedSize 哦,等一下,你刚刚意识到你正在传递整数文字和数字。嗯,在这种情况下 $Size 的输出必须伴随一个整数文字,即($大小)B
    • 是的,PowerShell 会自动将 37091MB 之类的值解析为整数。 20 是字符串生成器将容纳的容量(字符数),另请参见:docs.microsoft.com/en-us/dotnet/api/…
    • 输入 $Size 也必须伴随一个整数文字,对吗?所以我必须将 B 附加到这个 $Size = $Analysis_Server.Databases[$cube].EstimatedSize
    • 好吧,就我而言,该值是在没有整数文字的情况下生成的,例如 670。但 670 以字节为单位。如何附加到这个单元的输入? IE。 Format-Bytes ($Size -append 'B'))
    【解决方案2】:

    这里还有另外两种格式化字节大小的方法:

    1) 使用 switch()

    function Format-Size() {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
            [double]$SizeInBytes
        )
        switch ([math]::Max($SizeInBytes, 0)) {
            {$_ -ge 1PB} {"{0:N2} PB" -f ($SizeInBytes / 1PB); break}
            {$_ -ge 1TB} {"{0:N2} TB" -f ($SizeInBytes / 1TB); break}
            {$_ -ge 1GB} {"{0:N2} GB" -f ($SizeInBytes / 1GB); break}
            {$_ -ge 1MB} {"{0:N2} MB" -f ($SizeInBytes / 1MB); break}
            {$_ -ge 1KB} {"{0:N2} KB" -f ($SizeInBytes / 1KB); break}
            default {"$SizeInBytes Bytes"}
        }
    }
    

    2) 通过执行一个循环,将给定的字节大小重复除以 1024

    function Format-Size2 {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
            [double]$SizeInBytes
        )
    
        $units = "Bytes", "KB", "MB", "GB", "TB", "PB", "EB"
        $index = 0
    
        while ($SizeInBytes -gt 1024 -and $index -le $units.length) {
            $SizeInBytes /= 1024
            $index++
        }
        if ($index) {
            return '{0:N2} {1}' -f $SizeInBytes, $units[$index]
        }
    
        return "$SizeInBytes Bytes"
    }
    

    【讨论】:

    • 问题, 0:N2 中的 n2 是什么意思?另外,[math]::Max($SizeInBytes, 0) 中的 0 是什么
    • @Cataster N2format 有两位小数的数字。 [Math]::Max() 我这样做是为了确保开关只处理正数。
    【解决方案3】:

    我相信这是一个条件控制语句的简单实现,例如 IF()。

    Powershell 基础知识: IF Statements

    示例伪代码:

    If ($estimatedSize -lt 1)  {
    
     $newKbEstimateSize = $estimatedSize *  1000; //MB to KB
    
    }
    
    If ($estimatedSize  -gt 999.9)  {
    
      $newGbEstimatedSize = $estimatedSize / 1000; //MB to GB
    
    }
    

    【讨论】:

    • 这在技术上是正确的。但是,我相信提问者想要 Gibibytes (GiB) 和 Kibibytes (KiB) 的值,这需要您分别除以或乘以 1024
    • @MasonSchmidgall 不,我认为 Mathew 是正确的,除非我将 KB 与 KiB 混淆了?和 GB 与 GiB?我只是在寻找人们知道的日常单位,MB/GB ...两者之间有区别吗?我从来没有听说过 Kibi 或 Gibi ......如果是这样的话,那么条件句是否也必须从 1 更新为其他内容?和 999.9 到 1023.9?
    • @Cataster 1 MiB = 1024 KiB 和 1 MB = 1000 KB。这令人困惑,因为 Windows 将 MiB 称为 MB,而实际上并非如此。
    • @MasonSchmidgall 哇……也许这毕竟是不正确的……如果我将它们设为 1024,我应该将条件语句修复成什么?我要更改 1 和 999.9 吗?
    • 也意识到这不是 PowerShell。将发布准确的答案
    【解决方案4】:

    我会使用以下代码:

    Import-Module SqlServer
    
    $Analysis_Server = New-Object Microsoft.AnalysisServices.Server  
    $Analysis_Server.connect("$server")
    
    # Get the size in bytes
    $estimatedSize = $Analysis_Server.Databases[$cube].EstimatedSize
    
    $convertFactor = 1kb
    
    # Check if >= 1gib
    if ($estimatedSize -ge 1gb) {
        # Will convert to gibibytes
        $convertFactor = 1gb
    }
    elseif ($estimatedSize -ge 1mb) {
        # Will convert to mibibytes
        $convertFactor = 1mb
    }
    
    # Number of bytes / Number of Bytes in unit
    $estimatedSize = [math]::Round($estimatedSize / $convertFactor, 2)
    
    

    上面的内容以字节为单位,并使用numeric multipliers for data storage 进行比较。如果字节数更大,则使用该转换。否则,它只使用千字节

    【讨论】:

      猜你喜欢
      • 2012-08-02
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 2014-08-28
      • 2023-02-13
      相关资源
      最近更新 更多