Sorting PowerShell versions

后端 未结 5 533
無奈伤痛
無奈伤痛 2020-12-10 12:34

In PowerShell, if I have a list of strings containing versions, \"3.0.1.1\", \"3.2.1.1\", etc., how can I sort it the way System.Version would sort it in C#?

相关标签:
5条回答
  • 2020-12-10 13:04
    PS C:\> $ver="3.0.1.1","3.2.1.1"
    PS C:\> $ver|%{[System.Version]$_}|sort
    
    Major  Minor  Build  Revision
    -----  -----  -----  --------
    3      0      1      1
    3      2      1      1
    
    0 讨论(0)
  • 2020-12-10 13:13

    A version string can be cast to a Version object, and sort-object can be passed a script block and sort on the result.

    PS C:\Users\me> "3.11.0.1", "3.0.1.1", "3.2.1.1" | sort
    3.0.1.1
    3.11.0.1
    3.2.1.1
    
    PS C:\Users\me> "3.11.0.1", "3.0.1.1", "3.2.1.1" | sort {[version] $_}
    3.0.1.1
    3.2.1.1
    3.11.0.1
    

    (Added an extra version string to make the example actually meaningful.)

    0 讨论(0)
  • 2020-12-10 13:14

    Just to add another corner case: powershell treats this single digit kind of version '2' as invalid. Have to add '.0' to the end to create the version object before sorting:

    if($version  -match '^\d$')
    {
      $version = $version + '.0'
    }
    New-Object System.Version $version
    
    0 讨论(0)
  • 2020-12-10 13:15
    # I needed to sort historical versions (Octopus) with varying decimal formats.
    # Try # this (it is easy to add to a more complex expression sort)
    # Special Case "3.00.1.10.1.10" and "3.0.1.10.1.10" required the double sort
    # to work correctly
        $vers = @()`enter code here`
        $vers +=  @( "3.1.60",      "3.1.52","3.1.51")
        $vers +=  @( "3.00.46",     "3.00.36","3.50.2145.11")
        $vers +=  @( "3.50.2145.10","3.50.2145.9")
        $vers +=  @( "3.50.2145.8", "3.50.2145.7")
        $vers +=  @( "3.50.2145.6", "3.50.2145.5")
        $vers +=  @( "3.50.2145.4", "3.50.2145.3")
        $vers +=  @( "3.50.2145.2", "3.50.2145.1")
        $vers +=  @( "3.50.2145",   "3.50.2143")
        $vers +=  @( "3.50.2141",    "3.50.2135")    
        $vers +=  @( "3.0.1.10.1.1", "3.00.1.10.1.10")
        $vers +=  @( "2.1.3.4",      "3.0","3.")
        $vers +=  @( "3.0.1.10.1.100","3.0.1.10.1.10")
        $mySortAsc = @{Expression={ [regex]::Replace($_ ,'\d+', { $args[0].Value.PadLeft(20,'0') }) };Descending=$false}
        $mySortDesc = @{Expression={ [regex]::Replace($_ ,'\d+', { $args[0].Value.PadLeft(20,'0') }) };Descending=$true}    
        $nl = [Environment]::NewLine
        Write-Output ($nl + "Ascending Sort" + $nl);
        $vers | Sort-Object | Sort-Object $mySortAsc
        Write-Output ($nl + "Descending Sort" + $nl);
        $vers | Sort-Object -Descending | Sort-Object $mySortDesc
    <# Result
    Ascending Sort
    
    2.1.3.4
    3.
    3.0
    3.0.1.10.1.1
    3.0.1.10.1.10
    3.00.1.10.1.10
    3.0.1.10.1.100
    3.00.36
    3.00.46
    3.1.51
    3.1.52
    3.1.60
    3.50.2135
    3.50.2141
    3.50.2143
    3.50.2145
    3.50.2145.1
    3.50.2145.2
    3.50.2145.3
    3.50.2145.4
    3.50.2145.5
    3.50.2145.6
    3.50.2145.7
    3.50.2145.8
    3.50.2145.9
    3.50.2145.10
    3.50.2145.11
    
    Descending Sort
    
    3.50.2145.11
    3.50.2145.10
    3.50.2145.9
    3.50.2145.8
    3.50.2145.7
    3.50.2145.6
    3.50.2145.5
    3.50.2145.4
    3.50.2145.3
    3.50.2145.2
    3.50.2145.1
    3.50.2145
    3.50.2143
    3.50.2141
    3.50.2135
    3.1.60
    3.1.52
    3.1.51
    3.00.46
    3.00.36
    3.0.1.10.1.100
    3.00.1.10.1.10
    3.0.1.10.1.10
    3.0.1.10.1.1
    3.0
    3.
    2.1.3.4
    #>
    
    0 讨论(0)
  • 2020-12-10 13:25

    Just convert it to a Version and sort that way:

    $list = "3.0.1.1","3.2.1.1" 
    $sorted = $list | %{ new-object System.Version ($_) } | sort
    
    0 讨论(0)
提交回复
热议问题