我有一个脚本,其中包含字母数字字符串数组,例如VER11.10.00.000
,VER11.10.01.123
和VER9.09.02.050
。
我对此数组进行排序
[string[]] $HighestVER = $Version | Sort -Descending
foreach($element in $HighestVER) {
Write-Host $element
}
$Version
表示字符串的无序数组。
运行脚本时,结果如下:
VER9.16.00.000
VER9.15.00.000
VER9.14.00.000
VER9.13.00.000
VER11.9.00.000
VER11.8.00.000
VER11.7.00.000
VER11.6.00.000
VER11.5.00
VER11.4.00.000
VER11.3.00.016
VER11.3.00.000
VER11.2.00.000
VER11.10.00.000
如您所见,排序正在做某事,但未达到我的预期。我的预期输出是:
VER11.10.00.000
VER11.9.00.000
VER11.8.00.000
VER11.7.00.000
VER11.6.00.000
VER11.5.00
VER11.4.00.000
VER11.3.00.016
VER11.3.00.000
VER11.2.00.000
VER9.16.00.000
VER9.15.00.000
VER9.14.00.000
VER9.13.00.000
如何改进代码以匹配预期的输出?
编辑:
我无法使用[System.Version]
解决此问题,因为我的版本中包含字母字符。如果我删除前三个字符VER
并进行比较,那还是可以的,但是该版本的元素变得混乱了。
[string[]] $HighestVER = $Version2 | ForEach-Object { [System.Version] $_ } | Sort-Object -Descending | ForEach-Object { $_.toString() }
#[string[]] $HighestVER = $Version | Sort -Descending
foreach($element in $HighestVER) {
$element = "VER" + $element
Write-Host $element
}
这给了我这个输出:
VER11.10.0.0
VER11.9.0.0
VER11.8.0.0
VER11.7.0.0
VER11.6.0.0
VER11.5.0
VER11.4.0.0
VER11.3.0.16
VER11.3.0.0
VER11.2.0.0
VER9.16.0.0
VER9.15.0.0
VER9.14.0.0
VER9.13.0.0
最高版本号。用于比较和扩展版本列表(Dynamics NAV自动构建)。因此,格式不必相同。
答案 0 :(得分:1)
假设变量$vers
包含您提供的格式的版本数组,那么以下操作将起作用。
(($vers -replace "VER(?<Num>.*)",'${Num}' |
ForEach-Object {$_ -as [system.version]}) | Sort-Object -Desc) |
Foreach-Object {
("VER{0}.{1}.{2:D2}.{3:D3}" -f $_.Major,$_.Minor,$_.Build,$_.Revision) -replace "\.-\d+"}
此解决方案基本上提取版本号并将其转换为[system.version]
对象。可以使用Sort-Object
按照您要求的方式自然地对该对象进行排序。排序完成后,将重建输出,将那些版本对象转换为字符串。
-replace
运算符执行正则表达式替换。第一个从每行中删除字符串VER
。第二个命令删除由强制转换添加到[system.version]
的所有负整数。
最后一个Foreach-Object
正在使用格式运算符(-f
)格式化输出,它会加回在排序之前删除的字符串VER
。然后,它使用[system.version]
对象的每个部分来执行填充的串联。 {2:D2}
用前导0填充版本的第三数字部分,以使其为两位数。 {3:D3}
用前导0填充版本的第四个数字部分,使其成为三位数。
在进一步测试中,可以使用Lee_Dailey中的评论进行缩短,并提高效率:
$vers | Sort-Object {$_ -replace "VER(?<Num>.*)",'${Num}' -as [system.version]} -desc
答案 1 :(得分:0)
我建议使用Roman Kuzmin的$ToNatural
,它可以将字符串中的所有数字即时扩展到给定的位置(20):
## source Roman Kuzmin https://stackoverflow.com/a/5429048/6811411
$ToNatural = { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20,"0") }) }
$HighestVER = $Version | Sort -Descending $ToNatural
$HighestVER
VER11.10.00.000
VER11.9.00.000
VER11.8.00.000
VER11.7.00.000
VER11.6.00.000
VER11.5.00
VER11.4.00.000
VER11.3.00.016
VER11.3.00.000
VER11.2.00.000
VER9.16.00.000
VER9.15.00.000
VER9.14.00.000
VER9.13.00.000
答案 2 :(得分:0)
'
VER9.16.00.000
VER9.15.00.000
VER9.14.00.000
VER9.13.00.000
VER11.9.00.000
VER11.8.00.000
VER11.7.00.000
VER11.6.00.000
VER11.5.00
VER11.4.00.000
VER11.3.00.016
VER11.3.00.000
VER11.2.00.000
VER11.10.00.000
' | ConvertFrom-Csv -Header String |
Select-Object String,
@{Name='Version';Expression={[System.Version]::New($_.String.SubString(3))}} |
Sort-Object -Descending Version |
Select-Object -Expand String
VER11.10.00.000
VER11.9.00.000
VER11.8.00.000
VER11.7.00.000
VER11.6.00.000
VER11.5.00
VER11.4.00.000
VER11.3.00.016
VER11.3.00.000
VER11.2.00.000
VER9.16.00.000
VER9.15.00.000
VER9.14.00.000
VER9.13.00.000
String
属性创建一个单列对象列表Version
(类型)列Version
列对列表进行排序String
列中仅输出 原始 数据答案 3 :(得分:0)
您可以将脚本块与sort-object一起使用。有点像另一个答案。
PS C:\users\me> $version | sort { [version]($_ -replace 'VER') } -Desc
VER11.10.00.000
VER11.9.00.000
VER11.8.00.000
VER11.7.00.000
VER11.6.00.000
VER11.5.00
VER11.4.00.000
VER11.3.00.016
VER11.3.00.000
VER11.2.00.000
VER9.16.00.000
VER9.15.00.000
VER9.14.00.000
VER9.13.00.000