You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell自定义函数输出格式化及排序问题咨询

PowerShell 文件/文件夹大小格式化优化方案

我编写了多个类似如下的简易PowerShell函数(用于以易读格式输出文件/文件夹大小及名称),现需要解决三个格式化问题:

  • 让大小列右对齐、文件/文件夹名列左对齐
  • 替换制表符t,根据大小列的最大宽度(含[DIR]行)设置列宽,使其比最大宽度大2个字符
  • 让目录优先排序

原函数代码

function d ($name) {   # quick and dirty Size + Name
    $out = ""
    function Format-FileSize([int64]$size) {
        if ($size -gt 1TB) {[string]::Format("{0:0.00} TB", $size / 1TB)}
        elseif ($size -gt 1GB) {[string]::Format("{0:0.0} GB", $size / 1GB)}
        elseif ($size -gt 1MB) {[string]::Format("{0:0.0} MB", $size / 1MB)}
        elseif ($size -gt 1KB) {[string]::Format("{0:0.0} KB", $size / 1KB)}
        elseif ($size -gt 0) {[string]::Format("{0:0.0} B", $size)}
        else {""}
    }
    foreach ($i in (gci $folder | sort Length).FullName) {
        if (Test-Path -Path $i -PathType Container) {
            $size = "[DIR]"
            $size_out = "[DIR]" 
        }
        else {
            $size = (gci $i | select Length).Length
            $size_out = Format-FileSize($size)
            $size_total += $size
        }
        $out += "$size_out`t$(split-path $i -leaf)`n"
    }
    $out += "========`n$(Format-FileSize($size_total))  Total Size"
    $out
}

期望输出示例

[DIR]  0
   [DIR]  Setup
   [DIR]  Stuff
 69.0  B  Profiler.url
480.0  B  test-countdown.ps1
  1.0 KB  PinToTaskbar.ps1
  3.5 KB  Firefox2.reg
 70.5 KB  Firefox1.reg
124.7 KB  elevate.exe
  9.2 MB  Stardock Fences 4.0.0.3.exe
112.5 MB  pandoc.exe
 12.1 GB  image.iso
========
 12.2 GB  Total Size

优化后的完整函数

function d ($folder = ".") {
    # 定义大小格式化函数
    function Format-FileSize([int64]$size) {
        switch ($size) {
            { $_ -gt 1TB } { return "{0:0.00} TB" -f ($_ / 1TB) }
            { $_ -gt 1GB } { return "{0:0.0} GB" -f ($_ / 1GB) }
            { $_ -gt 1MB } { return "{0:0.0} MB" -f ($_ / 1MB) }
            { $_ -gt 1KB } { return "{0:0.0} KB" -f ($_ / 1KB) }
            { $_ -gt 0 }   { return "{0:0.0} B" -f $_ }
            default        { return "" }
        }
    }

    # 获取所有文件和目录,先按是否是目录排序(目录在前),再按大小排序
    $items = Get-ChildItem -Path $folder | Sort-Object -Property @{Expression='PSIsContainer'; Descending=$true}, Length

    # 收集所有大小显示文本(包括[DIR]和总计),用于计算最大宽度
    $sizeStrings = @()
    $totalSize = 0
    foreach ($item in $items) {
        if ($item.PSIsContainer) {
            $sizeStrings += "[DIR]"
        } else {
            $sizeStrings += Format-FileSize $item.Length
            $totalSize += $item.Length
        }
    }
    $sizeStrings += Format-FileSize $totalSize

    # 计算大小列宽度:最大字符串长度 + 2
    $sizeColumnWidth = ($sizeStrings | Measure-Object -Property Length -Maximum).Maximum + 2

    # 生成输出内容
    $output = @()
    foreach ($item in $items) {
        $sizeText = $item.PSIsContainer ? "[DIR]" : Format-FileSize $item.Length
        # 大小列右对齐,名称列左对齐
        $outputLine = "{0, -$sizeColumnWidth} {1}" -f $sizeText.PadLeft($sizeColumnWidth - 2), $item.Name
        $output += $outputLine
    }

    # 添加分隔线和总计行
    $output += "=" * ($sizeColumnWidth + 2 + (Get-ChildItem $folder | Select-Object -First 1 -ExpandProperty Name | Measure-Object -Property Length -Maximum).Maximum)
    $totalSizeText = Format-FileSize $totalSize
    $output += "{0, -$sizeColumnWidth} Total Size" -f $totalSizeText.PadLeft($sizeColumnWidth - 2)

    # 输出结果
    $output -join "`n"
}

问题解决说明

1. 大小列右对齐、名称列左对齐

使用PowerShell格式化运算符 -f 结合 PadLeft() 方法实现:

  • $sizeText.PadLeft($sizeColumnWidth - 2) 将大小文本填充到指定宽度,实现右对齐
  • 格式化字符串 "{0, -$sizeColumnWidth} {1}" 中的 - 标记确保名称列靠左显示

2. 动态设置列宽

  • 先收集所有需要显示的大小文本(包括[DIR]和总计大小),用 Measure-Object 计算最长字符串的长度
  • 列宽设为最大长度 + 2,预留足够留白
  • 替换原制表符t,改用计算好的列宽进行格式化输出

3. 目录优先排序

修改 Sort-Object 的排序规则,先按 PSIsContainer 属性降序排列(目录为$true,会排在前面),再按文件大小排序:

Sort-Object -Property @{Expression='PSIsContainer'; Descending=$true}, Length

内容的提问来源于stack exchange,提问作者YorSubs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 12:20:54