如何在PowerShell中按数值对字符串排序
我正在尝试创建一个脚本,该脚本将列出我需要列出的服务器以及从每个服务器返回的延迟,我需要根据ping以升序或降序排列该列表 到目前为止,我提出的方法基本上满足了我的要求,但是如果在一台服务器上返回的ping值高于100,那么如果其他值以大于1的值开始,则认为它们更高 我知道我需要ping值作为一个整数返回,但我还没有弄清楚如何在不删除服务器名的情况下实现这一点 不管怎样,这是我到目前为止想到的如何在PowerShell中按数值对字符串排序,powershell,sorting,Powershell,Sorting,我正在尝试创建一个脚本,该脚本将列出我需要列出的服务器以及从每个服务器返回的延迟,我需要根据ping以升序或降序排列该列表 到目前为止,我提出的方法基本上满足了我的要求,但是如果在一台服务器上返回的ping值高于100,那么如果其他值以大于1的值开始,则认为它们更高 我知道我需要ping值作为一个整数返回,但我还没有弄清楚如何在不删除服务器名的情况下实现这一点 不管怎样,这是我到目前为止想到的 function TestNetwork { $global:array = @("<S
function TestNetwork {
$global:array = @("<ServerName>:<ipaddress>"; "<ServerName>:<ipaddress>"; "<ServerName>:<ipaddress>")
foreach ($str in $global:array) {
$avg = 0
$server = $($str -split ":")[0]
$PingServer = Test-Connection -Count 3 $server
$avg = ($PingServer | Measure-Object ResponseTime -Average)
$calc = [System.Math]::Round($avg.Average)
$output = "{000} | " -f $($calc) + $server
$Output
}
}
TestNetwork | Sort numerical -Descending `
功能测试网络{
$global:array=@(“:”;“:”;“:”)
foreach($global:array中的str){
$avg=0
$server=$($str-split):“[0]
$PingServer=测试连接-计数3$server
$avg=($PingServer |测量对象响应时间-平均值)
$calc=[System.Math]::四舍五入($avg.Average)
$output=“{000}|”—f$($calc)+$server
$Output
}
}
TestNetwork |数字排序-降序`
这是我得到的结果
75 | Server
73 | Server
110 | Server
75 |服务器
73 |服务器
110 |服务器
以下是一种替代方法,可使输出更易于排序和格式化:
function Test-Network
{
$array = ("<ServerName>","<ipaddress>"), ("<ServerName>","<ipaddress>"), ("<ServerName>","<ipaddress>")
$array | ForEach-Object {
[PsCustomObject]@{
AvgResponse = [Math]::Round((Test-Connection -Count 3 $_[0] | Measure-Object ResponseTime -Average).Average)
Server = $_[0]
}
}
}
Test-Network |
Sort-Object AvgResponse -Descending
输出这样的自定义对象而不是字符串的好处是,您可以在输出上使用进一步的PowerShell技术,如排序、分组等
请注意其他几点:
- 除非您打算在函数外部使用数组,否则无需将其声明为“全局” 除非你真的需要格式<代码>:“<代码> >的名字,考虑不同的方式存储它们。我使用了一个数组数组,这使得在本例中更容易使用,因为每次都不必拆分字符串
- 您应该根据PowerShell动词-名词命名标准命名函数,因此
,而不是测试网络
测试网络
function Test-Network
{
$array = ("<ServerName>","<ipaddress>"), ("<ServerName>","<ipaddress>"), ("<ServerName>","<ipaddress>")
$array | ForEach-Object {
[PsCustomObject]@{
AvgResponse = [Math]::Round((Test-Connection -Count 3 $_[0] | Measure-Object ResponseTime -Average).Average)
Server = $_[0]
}
}
}
Test-Network |
Sort-Object AvgResponse -Descending
输出这样的自定义对象而不是字符串的好处是,您可以在输出上使用进一步的PowerShell技术,如排序、分组等
请注意其他几点:
- 除非您打算在函数外部使用数组,否则无需将其声明为“全局” 除非你真的需要格式<代码>:“<代码> >的名字,考虑不同的方式存储它们。我使用了一个数组数组,这使得在本例中更容易使用,因为每次都不必拆分字符串
- 您应该根据PowerShell动词-名词命名标准命名函数,因此
,而不是测试网络
测试网络
有几种方法可以解决您的问题 您可以将整数排序顺序和字符串排序顺序对齐为: 您还可以从字符串中提取数字,将其转换回整数,并将其用作排序属性:
... | Sort-Object {[int]($_ -replace '(\d+).*', '$1')} -Descending
然而,我不建议任何一种方法。做事情的高级方法是使用对象,因此,仅当您有理由这样做(例如创建文本输出)时,才将数据包装在自定义对象中并将其转换为字符串:
这样,您就可以“自然”地对数据进行排序:
TestNetwork | Sort ResponseTime -Descending | ForEach-Object {
'{0,3} | {1}' -f $_.ResponseTime, $_.ComputerName
}
或
有几种方法可以解决您的问题 您可以将整数排序顺序和字符串排序顺序对齐为: 您还可以从字符串中提取数字,将其转换回整数,并将其用作排序属性:
... | Sort-Object {[int]($_ -replace '(\d+).*', '$1')} -Descending
然而,我不建议任何一种方法。做事情的高级方法是使用对象,因此,仅当您有理由这样做(例如创建文本输出)时,才将数据包装在自定义对象中并将其转换为字符串:
这样,您就可以“自然”地对数据进行排序:
TestNetwork | Sort ResponseTime -Descending | ForEach-Object {
'{0,3} | {1}' -f $_.ResponseTime, $_.ComputerName
}
或
您应该使用CustomObject输出结果,而不是将数字格式化为字符串。使用不同的字符串格式运算符右对齐数字
$output=“{0,3}|””-f$($calc)+$server
,或者在排序时使用aTestNetwork |排序对象-desend{[regex]::Replace($),{$args[0]。Value.PadLeft(20)}
您应该使用CustomObject输出结果,而不是将数字格式化为字符串。使用不同的字符串格式运算符将数字右对齐$output=“{0,3}|”-f$($calc)+$server
或在排序TestNetwork |排序对象-desend{[regex]::Replace($),\d+,{$args[0].Value.PadLeft(20)}
太棒了,感谢您的回复,这非常有效!我不使用自定义对象的原因是,我需要输出为一行,可以通过开关获取和转换。再次感谢,这是一个巨大的帮助!太棒了,谢谢你的回复,这很好用!我不使用自定义对象的原因是,我需要输出为一行,可以通过开关获取和转换。再次感谢,这是一个巨大的帮助!
TestNetwork | Sort ResponseTime -Descending | Export-Csv 'output.csv' -NoType