PowerShell 自定义订单排序
PowerShell Custom Order Sorting
我有一个简单的脚本,它运行第 3 方应用程序的 cmdlet 并输出一个包含 3 列的 table - Name
、Result
、JobName
。 Result
仅包含以下三个值之一:Success
、Warning
或 Failed
。
输出:
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
我想做的是按 Result
列对 table 进行排序,但按照以下自定义顺序(重要性顺序):Failed
、Warning
,然后 Success
。
例子
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
如何实现?
您可以使用 Array.IndexOf()
,它可以有效地将字符串转换为数字:
$importance = "Failed", "Warning", "Success"
$result | Sort-Object { $importance.IndexOf($_.Result) }
捕获:Result
中的任何意外值都将排序到顶部,因为 IndexOf
将 return -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
这是一个脚本块选项:
ForEach ($Result in 'Success','Warning','Failed') {
$Obj | Where-Object {$_.Result -eq $Result } | Sort-Object Name
}
假定您的 cmdlet 已将原始对象输出到名为 $Obj
.
的变量中
我是这样做的,你传递包含的对象和你想要排序的 属性 名称,它会带你返回一个正确排序的对象,而不必尝试绕过排序对象命令(这很棒)不知道它的幕后发生了什么。希望这对您有所帮助。
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;
我有一个简单的脚本,它运行第 3 方应用程序的 cmdlet 并输出一个包含 3 列的 table - Name
、Result
、JobName
。 Result
仅包含以下三个值之一:Success
、Warning
或 Failed
。
输出:
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
我想做的是按 Result
列对 table 进行排序,但按照以下自定义顺序(重要性顺序):Failed
、Warning
,然后 Success
。
例子
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
如何实现?
您可以使用 Array.IndexOf()
,它可以有效地将字符串转换为数字:
$importance = "Failed", "Warning", "Success"
$result | Sort-Object { $importance.IndexOf($_.Result) }
捕获:Result
中的任何意外值都将排序到顶部,因为 IndexOf
将 return -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
这是一个脚本块选项:
ForEach ($Result in 'Success','Warning','Failed') {
$Obj | Where-Object {$_.Result -eq $Result } | Sort-Object Name
}
假定您的 cmdlet 已将原始对象输出到名为 $Obj
.
我是这样做的,你传递包含的对象和你想要排序的 属性 名称,它会带你返回一个正确排序的对象,而不必尝试绕过排序对象命令(这很棒)不知道它的幕后发生了什么。希望这对您有所帮助。
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;