PowerShell按自定义顺序排序

时间:2018-02-09 08:16:27

标签: powershell sorting customization

我有一个简单的脚本,它运行第三方应用程序的cmdlet并输出一个包含3列的表 - Name,Result,JobName。 "结果"仅包含以下三个值之一:成功,警告,失败。示例输出:

Name      Result   JobName                          
----      ------   -------                          
server1   Success  servers-A            
server2   Success  servers-A            
server3   Warning  servers-A            
server4   Success  servers-A   
server5   Warning  servers-B            
server6   Success  servers-B            
server7   Failed   servers-C            
server8   Failed   servers-C   

我想要做的是按结果列排序表,但按以下自定义顺序排序(重要性顺序):失败,警告,成功。例如:

Name    Result  JobName    
----    ------  -------                      
server7 Failed  servers-C            
server8 Failed  servers-C
server3 Warning servers-A            
server5 Warning servers-B            
server1 Success servers-A            
server2 Success servers-A            
server4 Success servers-A   
server6 Success servers-B

如何实现这一目标?提前谢谢!

3 个答案:

答案 0 :(得分:4)

您可以使用Array.IndexOf(),它可以有效地将字符串转换为数字:

$importance = "Failed", "Warning", "Success"

$result | Sort-Object { $importance.IndexOf($_.Result) }

Catch:Result中的任何意外值都将排序到顶部,因为IndexOf将为无法找到的值返回-1。

测试:

$importance = "Failed", "Warning", "Success"

$list = @(
    @{ Result = "Warning" }
    @{ Result = "Success" }
    @{ Result = "Failed" }
)

$list | Sort-Object { $importance.IndexOf($_.Result) }

结果:

Name                           Value                                                                                                                                                                 
----                           -----                                                                                                                                                                 
Result                         Failed                                                                                                                                                                
Result                         Warning                                                                                                                                                               
Result                         Success                                                                                                                                                               

答案 1 :(得分:2)

我喜欢Tomalak的回答,这是另一个不那么优雅的选择:

ForEach ($Result in 'Success','Warning','Failed') {
    $Obj | Where-Object {$_.Result -eq $Result } | Sort-Object Name
}

假设您的cmdlet已将原始对象输出到名为$Obj的变量。

答案 2 :(得分:0)

这是我这样做的方法,您传递包含对象和要排序的属性名称,它会带您返回一个正确排序的对象,而无需尝试解决 sort-object 命令(这很棒)不知道在它的引擎盖下发生了什么。希望这会有所帮助。

function sortObjectManually
{
    Param(
    [parameter(Mandatory=$true)]
    $unsortedObject,
    [parameter(Mandatory=$true)]
    $propertyName
    )
    
    $sortedObject = New-Object System.Collections.ArrayList;
    foreach ($object in $unsortedObject)
    {
        if ($sortedObject.Count -eq 0)
        {
            $sortedObject.Add($object) | Out-Null;
        }
        else
        {
            $inserted = $false;
            for ($i = 0; $i -lt $sortedObject.Count; $i++)
            {
                if ($object.$propertyName -lt $sortedObject[$i].$propertyName)
                {
                    $sortedObject.Insert($i, $object);
                    $inserted = $true;
                    break;
                }
            }
            
            if ($inserted -eq $false)
            {
                $sortedObject.Add($object) | Out-Null;
            }
        }
    }
    
    return $sortedObject;
}

cls;
$prop = "ServerName";
$results = sortObjectManually -unsortedObject $endInvokeArr -propertyName $prop;