如何为排序对象Cmdlet提供自己的比较?

时间:2019-03-27 14:54:27

标签: powershell

我有一个路径列表。文件名包含一个版本号,我想按此编号对列表进行排序。

我尝试使用List<T>.Sort方法和Sort-Object Cmdlet,但是使用.NET时语法有问题,我不知道Sort-Object是否支持我的需求。

$files包含路径,类型为List<string>。对C#感到满意之后,我尝试了以下操作:

$files.Sort(delegate($pathX, $pathY){
    [some code to extract version number from path, so $x,$y contains just the version number]
    $versionX = New-Object system.version($x);
    $versionY = New-Object system.version($y);
    return $versionX.CompareTo($versionY)
})

由于委托关键字,此操作已失败,因为我不知道如何为Powershell中的List<T>.Sort方法提供必要的功能。

然后我偶然发现了Cmdlet Sort-Object,但是我不知道如何将上面的等效代码传递给它。

1 个答案:

答案 0 :(得分:3)

尝试这样的事情:

$paths = "C:\Files\File1.0.3.txt",         
         "C:\Files\File4.4.2.txt",
         "C:\Files\File2.0.0.txt",
         "C:\Files\File0.0.3.txt"

$paths |
  Sort-Object {$_ -match "(?<ver>(\d+\.){2}\d+)" | Out-Null; [Version]$matches.ver}

给出以下输出:

C:\Files\File0.0.3.txt
C:\Files\File1.0.3.txt
C:\Files\File2.0.0.txt
C:\Files\File4.4.2.txt

调整版本提取代码/模式以适合实际的路径格式。

编辑 根据@LotPings的评论,这里有一个更清晰的解释,说明为什么需要这种更复杂的过程进行排序:

使用我的原始(选择不佳)示例数据,简单的排序将给出预期的排序顺序,而无需任何其他代码:

$paths = "C:\Files\File1.0.3.txt",
         "C:\Files\File4.4.2.txt",
         "C:\Files\File2.0.0.txt",
         "C:\Files\File0.0.3.txt"

$paths | Sort-Object

C:\Files\File0.0.3.txt
C:\Files\File1.0.3.txt
C:\Files\File2.0.0.txt
C:\Files\File4.4.2.txt

但是,这不适用于其他一些有效的版本值。例如:

$paths = "C:\Files\File10.0.0.txt",         
         "C:\Files\File2.0.0.txt",
         "C:\Files\File20.0.0.txt",
         "C:\Files\File1.0.0.txt"

$paths | Sort-Object

C:\Files\File1.0.0.txt
C:\Files\File10.0.0.txt
C:\Files\File2.0.0.txt
C:\Files\File20.0.0.txt

使用原始代码给出正确的顺序:

C:\Files\File1.0.0.txt
C:\Files\File2.0.0.txt
C:\Files\File10.0.0.txt
C:\Files\File20.0.0.txt