正确排序包含版本号的列表

r3plica

所以,我有一个看起来像这样的版本列表:

v1.1.0
v1.2.0
v1.3.0
v1.4.0
v1.5.0
v1.7.0
v1.8.0
v1.9.0
v2.0.0
v2.1.0
v2.10.0
v2.11.0
v2.12.0
v2.2.0
v2.3.0
v2.4.0
v2.5.0
v2.6.0
v2.7.0
v2.8.0
v2.9.0

问题是,它们的订购顺序不正确。我是Powershell的新手,所以在尝试对它们进行排序时遇到了一些问题。我尝试这样做:

$tags = git tag
$versions = $tags | %{ new-object System.Version ($_) } | sort

但是我得到这个错误:

“ new-object:使用” 1“参数调用” .ctor“的异常:”版本字符串部分太短或太长。“ 在第1行:char:24 + $ versions = $ tags | %{新对象System.Version($ _)} | 排序+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CategoryInfo:InvalidOperation:(:) [New-Object],MethodInvocationException + FullyQualifiedErrorId: ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

有人可以帮忙吗?


更新资料

我使用了一种看起来像这样的解决方案:

$location = Get-Location
$path = $location.tostring() + "\CHANGELOG.md"
$tags = git tag
$i = 0

Clear-Content $path
Add-Content $path "Change Log"
Add-Content $path "=========="
Add-Content $path " "

$ToNatural = { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20) }) }
$tags | Sort-Object $ToNatural

foreach($tag in $tags) 
{
    if (-NOT ($tag -match "v(\d+\.)(\d+\.)(\*|\d+)")) { continue }
    $i = $i + 1
    if ($i -eq 0) { continue }
    $tag
    If ($i -gt 0) {
        $previous = $tags[$i - 1]

        Add-Content $path " "
    }
}

这种工作方式,但是所有标签似乎都是控制台记录的,它显示了这一点:

1.6.0
changeDeliveryFieldAccess
orders/autoComplete
returns/autoComplete
save-lines-dates
services/serviceDetails
tile-colours
users/confirmation
v0.1
v1.1.0
v1.2.0
v1.3.0
v1.4.0
v1.5.0
v1.7.0
v1.8.0
v1.9.0
v2.0.0
v2.1.0
v2.2.0
v2.3.0
v2.4.0
v2.5.0
v2.6.0
v2.7.0
v2.8.0
v2.9.0
v2.10.0
v2.11.0
v2.12.0
v.2.7.1

如您所见,其中有些是我不想要的。特别:

1.6.0
changeDeliveryFieldAccess
orders/autoComplete
returns/autoComplete
save-lines-dates
services/serviceDetails
tile-colours
users/confirmation
v.2.7.1

从我的清单中删除这些内容后,顺序将是正确的:)


更新2

因此,我尝试了另一种更好的解决方案:

$ location =获取位置$ path = $ location.tostring()+“ \ CHANGELOG.md” $ tags = git标签$ i = 0

Clear-Content $path
Add-Content $path "#Change Log"
Add-Content $path "=========="
Add-Content $path " "

$tags |
  Where-Object { $_.Substring(1) -as [version] } |
   Sort-Object { [version] $_.Substring(1) }

foreach($tag in $tags) {
    write-host "$($tag) is ok"
}

我不确定我是否做对了,但这是上面代码的输出:

1.6.0 is ok
changeDeliveryFieldAccess is ok
orders/autoComplete is ok
returns/autoComplete is ok
save-lines-dates is ok
services/serviceDetails is ok
tile-colours is ok
users/confirmation is ok
v.2.7.1 is ok
v0.1 is ok
v1.1.0 is ok
v1.2.0 is ok
v1.3.0 is ok
v1.4.0 is ok
v1.5.0 is ok
v1.7.0 is ok
v1.8.0 is ok
v1.9.0 is ok
v2.0.0 is ok
v2.1.0 is ok
v2.10.0 is ok
v2.11.0 is ok
v2.12.0 is ok
v2.2.0 is ok
v2.3.0 is ok
v2.4.0 is ok
v2.5.0 is ok
v2.6.0 is ok
v2.7.0 is ok
v2.8.0 is ok
v2.9.0 is ok
mklement0

tl; dr

稍后,您指出了$tags数组还包含其他非版本字符串,因此必须将其过滤掉

$sortedVersionTags = $tags |
  Where-Object { $_.Substring(1) -as [version] } |
   Sort-Object { [version] $_.Substring(1) }
  • Where-Object { $_.Substring(1) -as [version] }只传递那些可以转换[version]System.Version)对象的字符串-as [version]-在v开始时.Substring(1)删除;忽略删除v是您的最初问题);-as操作者或者返回一个成功转换的值或$null

  • Sort-Object然后将筛选出的标签作为版本号进行排序,从而产生正确的顺序-请参阅下一部分以获得解释。

  • $sortedVersionTags然后仅接收v经过正确排序的原始形式(作为-前缀字符串)的版本标签


v版本号中[System.Version]前缀可防止将其转换为实例。只需先将其删除(而不是从输入本身中删除;而是暂时删除它,以创建版本信息对象,例如v1.1.0-> 1.1.0)。

此外,您的命令可以简化:

# $tags is an array of lines, as output by `git tag`
$tags | Sort-Object { [version] $_.Substring(1) }
  • [version]是PowerShell中内置的类型加速器(简称),它指向[System.Version][1]

  • 您可以简单地字符串强制转换为[version],这比使用更加简洁,快捷New-Object

  • Sort-Object通过脚本块(接受表达式{ ... }来代替固定属性进行排序;在脚本块中,$_是指给定的输入对象;$_.Substring(1)只需删除第一个字符(v)。

    • 请注意,出于排序目的,该表达式仅临时使用仍然输出原始字符串-排序。Sort-Object

使用示例输入,上面的结果(请注意v2.10.0后面如何正确排序v2.9.0,而词汇排序不是这种情况):

v1.1.0
v1.2.0
v1.3.0
v1.4.0
v1.5.0
v1.7.0
v1.8.0
v1.9.0
v2.0.0
v2.1.0
v2.2.0
v2.3.0
v2.4.0
v2.5.0
v2.6.0
v2.7.0
v2.8.0
v2.9.0
v2.10.0
v2.11.0
v2.12.0

如果您希望输出System.Version实例而不是输入字符串,该命令将变得更加简单(PSv3 +语法):

[version[]] $tags.Substring(1) | Sort-Object

如果有可能无法以这种方式转换其中包含的所有字符串$tags(由于没有v<version>格式),请使用以下(PSv4 +语法):

# Reports non-convertible lines as non-terminating errors, but processes all others.
$tags.ForEach({ [version] $_.Substring(1) }) | Sort-Object

这种方法确保遇到无法转换的字符串不会破坏整体命令

  • 那些可以被转换,和被输出。

  • 那些无法转换的文件将导致打印到控制台的错误,并且也将在$Error以后的自动收集中反映出来。您可以使用取消控制台输出2>$null


[1]通常,PowerShell允许您省略System.类型名称中前缀。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章