【问题标题】:Format-List: sort properties by nameFormat-List:按名称对属性进行排序
【发布时间】:2020-03-16 18:02:31
【问题描述】:

是否可以按属性名称对 Format-List cmdlet 的输出进行排序?
假设我有一个具有两个属性“A”和“B”的对象 $x,当我用它运行 Format-List 时,我得到了

(PS) > $x | Format-List
B : value b
A : value a

我想要

(PS) > $x | Format-List 
A : value a
B : value b

注意:我应该从一开始就指定,与具有“A”和“B”属性的示例不同,我必须处理的真实对象具有相当多的属性,未来可能会添加新的,所以我不知道所有的属性名称。

【问题讨论】:

    标签: sorting powershell


    【解决方案1】:

    AFAIK,Format-List 不提供这样的选项。

    对于您的特定示例,这应该有效:

    $x | Select-Object A, B | Format-List
    

    如果属性集不固定/未知,则使用Get-Member 和一些预处理为Select-Object 制作排序参数数组时,该过程将更加棘手。

    编辑:

    在这里(让我们使用 $host 而不是 $x):

    $host | Select-Object ([string[]]($host | Get-Member -MemberType Property | %{ $_.Name } | Sort-Object)) | Format-List
    

    Christopher 是对的,Select-Object 不是绝对需要的:

    $host | Format-List ([string[]]($host | Get-Member -MemberType Property | %{ $_.Name } | Sort-Object))
    

    【讨论】:

    • 通过使用PowerShell命令别名,上面的答案可以缩短为:$x | fl ([string[]]($x | gm -m Property | %{$_.Name} | sort))
    【解决方案2】:

    接受的答案没有错,但 真的 一次性的快速和肮脏的选项 - 不需要将集合已经在变量中 - 可能是......

    ... | Format-List | Out-String -Stream | Sort-Object
    

    ...对Format-List 输出的每一行进行排序。

    请注意,进入下一行的任何属性值都将被破坏(并且可能出现在输出的顶部),但这可以通过稍微不太记忆的...

    ... | Format-List | Out-String -Stream -Width ([Int32]::MaxValue) | Sort-Object
    

    ...以列缩进为代价。

    当然,Out-String 调用会丢失所有对象/管道信息,尽管考虑到Format-List 也是如此——到那时你可能不会在意。

    【讨论】:

      【解决方案3】:

      我能想到的最接近的方法是在旧对象的基础上创建一个新的 psobject,但属性已排序,例如:

      $x | %{$obj = new-object psobject; `
             $_.psobject.properties | Sort Name | `
                 %{Add-Member -Inp $obj NoteProperty $_.Name $_.Value}; $obj} | fl
      

      你可以变得更漂亮,给新的 psobject 一个与旧的匹配的类型名,等等。

      【讨论】:

      • 我也喜欢这个解决方案...+1
      【解决方案4】:

      扩展 Christopher 的想法,使用 get-memberformat-list -Property

      $x | fl -property ($x| gm | sort name).name
      

      【讨论】:

        【解决方案5】:

        如果您正在处理少量属性,您可以使用 -Property 参数指定它们的顺序。

        这是一个例子:

        Format-List -Property Owner, Path
        

        如果您有很多属性,我不确定是否有任何简单的方法可以像 Roman 所说的那样在 Format-List 中对它们进行排序。

        【讨论】:

          【解决方案6】:

          这似乎工作正常(已编辑,因此它接受管道输入):

          function Format-SortedList
          {
              param (
                  [Parameter(ValueFromPipeline = $true)]
                  [Object]$InputObject,
                  [Parameter(Mandatory = $false)]
                  [Switch]$Descending
              )
          
              process
              {
                  $properties = $InputObject | Get-Member -MemberType Properties
          
                  if ($Descending) {
                      $properties = $properties | Sort-Object -Property Name -Descending
                  }
          
                  $longestName = 0
                  $longestValue = 0
          
                  $properties | ForEach-Object {
                      if ($_.Name.Length -gt $longestName) {
                          $longestName = $_.Name.Length
                      }
          
                      if ($InputObject."$($_.Name)".ToString().Length -gt $longestValue) {
                          $longestValue = $InputObject."$($_.Name)".ToString().Length * -1
                      }
                  }
          
                  Write-Host ([Environment]::NewLine)
          
                  $properties | ForEach-Object { 
                      Write-Host ("{0,$longestName} : {1,$longestValue}" -f $_.Name, $InputObject."$($_.Name)".ToString())
                  }
              }
          }
          
          $Host, $MyInvocation | Format-SortedList
          $Host, $MyInvocation | Format-SortedList -Descending
          

          【讨论】:

            【解决方案7】:

            我确信您可以实现所需的输出。我建议您尝试使用 Sort-Object(或普通排序)和 Group-Object(普通组)

            我的想法是将排序或组放在 | 之前格式列表

            因此 $x |排序对象-属性 xyz |格式列表

            【讨论】:

            • 此方法将根据属性 xyz 的值对对象进行排序,但不会对每个单独对象的属性进行排序。
            【解决方案8】:

            通过将 Select-Object 与计算属性 (@{}) 一起使用,然后将其排除 (-ExcludeProperty),您还可以根据需要对属性进行排序。即使您不知道会发生什么,这也有效。

            @(
                [PSCustomObject]@{
                    Color   = 'Green'
                    Type    = 'Fruit'
                    Name    = 'kiwi'
                    Flavour = 'Sweet'
                }
            ) | Select-Object @{Name = 'Flavour'; Expression = { $_.Flavour } },
            @{Name = 'Name'; Expression = { $_.Name } }, * -ExcludeProperty Name, Flavour |
            Format-List
            

            输出:

            Flavour : Sweet
            Name    : kiwi
            Color   : Green
            Type    : Fruit
            

            【讨论】:

              猜你喜欢
              • 2010-11-24
              • 1970-01-01
              • 1970-01-01
              • 2022-08-19
              • 1970-01-01
              • 2023-03-27
              • 2021-09-05
              相关资源
              最近更新 更多