我需要对 IP 地址数组进行排序,并输出排序后的数组以在每个 IP 地址之间包含“,”
$ip = "192.168.0.10, 192.168.0.12, 192.168.0.11, 192.168.0.9"
$ip =$ip.ToString()
$a = $ip.Split(",")
$new = for ($i=0;$i -lt $a.count;$i+=1) {$a[$i]}
$new | sort
输出以下内容(请注意,第 4 个 IP 八位字节未正确排序):
192.168.0.11
192.168.0.12
192.168.0.9
192.168.0.10
带有“,”分隔符的预期(已排序)输出:
“192.168.0.9”、“192.168.0.10”、“192.168.0.11”、“192.168.0.12”
谢谢您的帮助!
IP 地址的排序方式与版本相同。在排序中投射项目效果很好:
$ip = "192.168.0.10, 192.168.0.12, 192.168.0.11, 192.168.0.9"
$ip =$ip.ToString()
$a = $ip.Split(",")
$new = for ($i=0;$i -lt $a.count;$i+=1) {$a[$i]}
$new | sort {[Version]$_}
顺便说明一下,.ToString() 和 for 循环是不必要的。以下结果相同。
$ip = "192.168.0.10, 192.168.0.12, 192.168.0.11, 192.168.0.9"
$new = $ip.Split(",")
$new | sort {[Version]$_}
你有两件事发生:
当您分割字符串时,您还需要修剪它 - 您实际排序的值是:
192.168.0.10
192.168.0.12
192.168.0.11
192.168.0.9
注意第 2-4 项的前导空格。
(空格)字符在1
字符之前排序,因此
192.160.0.10
最终位于列表的底部,排序结果为:
192.168.0.11
192.168.0.12
192.168.0.9
192.168.0.10
您可以通过Trim()
修改您的值以删除任何前导或尾随空格来解决此问题:
$a = $ip.Split(",").Trim()
(这使用 Member-Access Enumeration 来修剪分割结果中的所有值,并使用 Trim()
的结果创建一个新数组,所以现在我们的输出是:
192.168.0.10
192.168.0.11
192.168.0.12
192.168.0.9
看起来好一点,但由于不同的原因它仍然是错误的......词法排序
词法(字典)排序,而不是 IP 地址八位字节的语义排序。
由于您的所有地址都有相同的前 3 个八位字节,如果我们对最后一个八位字节进行排序,我们会得到:
"10, 12, 11, 9".Split(",").Trim() | sort
10
11
12
9
基本上,9
对
1
进行排序,因此
9
出现在
10
、
11
和
12
之后。有关稍微复杂一点的示例,请参见:
"1, 2, 10, 11, 12, 20, 21, 22, 100, 200".Split(",").Trim() | sort
1
10
100
11
12
2
20
200
21
22
3
所有内容均按字符串中的第一个字符排序,then按第二个字符排序,then按第三个字符排序,而不是按它们的数值排序。
回答解析为您想要的排序形式。
幸运的是,您可以将 IP 地址字符串转换为根据八位字节值排序的[int]
- 请参阅https://stackoverflow.com/a/36560061/3156906 您还可以根据输入数组对计算值进行排序 - 将这两个放在一起给出:
$ip = "192.168.0.10, 192.168.0.12, 192.168.0.11, 192.168.0.9";
$ip.Split(",").Trim() | sort-object {
# from https://stackoverflow.com/a/36560061/3156906
$bytes = [System.Net.IPAddress]::Parse($_).GetAddressBytes();
if( [BitConverter]::IsLittleEndian )
{
[Array]::Reverse($bytes);
}
[BitConverter]::ToUInt32($bytes, 0);
}
192.168.0.9
192.168.0.10
192.168.0.11
192.168.0.12
这也适用于其他一些问题,例如:
$ip = "192.168.0.100, 192.168.0.12, 99.99.99.99, 192.168.0.9"
$ip.Split(",").Trim() | sort-object {
...
}
# 99.99.99.99
# 192.168.0.9
# 192.168.0.12
# 192.168.0.100