如何在PowerShell中按字符串的数值对字符串进行排序

时间:2018-04-25 22:18:07

标签: powershell sorting

我正在尝试创建一个脚本,列出我需要列出的服务器以及从每个服务器返回的延迟,我需要基于ping的列表按升序或降序排列。

到目前为止,我提出的基本上已经给出了我想要的内容,但是如果在一台服务器上返回的ping超过100,那么如果它们的值大于1,则认为其他值更高

据我所知,我需要以整数形式返回ping值,但是我还没有能够确定如何在不删除服务器名称的情况下完成该操作。

无论如何,这是我到目前为止所提出的

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 `

以下是我得到的结果

75 | Server    
73 | Server  
110 | Server  

2 个答案:

答案 0 :(得分:1)

有几种方法可以解决您的问题。

您可以format将整数排序顺序和字符串排序顺序对齐为LotPings suggested的数字:

'{0,3} | {1}' -f $calc, $server

您还可以从字符串中提取数字,将其转换回整数,并将其用作排序属性:

... | Sort-Object {[int]($_ -replace '(\d+).*', '$1')} -Descending

但是,我不建议采用任何一种方法。 PoSh的处理方式是将对象作为Olaf pointed out处理,所以只有在你有理由的情况下才将数据包装在自定义对象中并将它们转换为字符串(例如创建文本输出):

foreach ($str in $global:array) {
    ...
    New-Object -Type PSObject -Property ([ordered]@{
        'ComputerName' = $server
        'ResponseTime' = $calc
    })
}

你可以这样自然地#34;对数据进行排序:

TestNetwork | Sort ResponseTime -Descending | ForEach-Object {
    '{0,3} | {1}' -f $_.ResponseTime, $_.ComputerName
}

TestNetwork | Sort ResponseTime -Descending | Export-Csv 'output.csv' -NoType

答案 1 :(得分:0)

以下是一种替代方法,可以提供可以更轻松地进行排序和格式化的输出:

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

输出将如下所示:

AvgResponse Server  
----------- ------  
        363 server1
         12 server2
          2 server3

输出像这样的自定义对象而不是字符串的好处是你可以在输出上使用更多的PowerShell技术,例如排序,分组等。

请注意其他几点:

  • 除非您打算在函数之外使用数组,否则无需将其声明为“全局”
  • 除非您确实需要"<ServerName>:<ipaddress>"格式的名称,否则请考虑以不同方式存储它们。我已经使用了一个数组数组,这使得在这种情况下更容易使用,因为你不必每次都分割一个字符串。
  • 您应该根据PowerShell Verb-Noun命名标准命名您的函数,因此Test-Network而不是TestNetwork