Use Sort-Object
with a calculated property (a script block ({ ... }
) that is evaluated for each input object, reflected in $_
) as follows:
# Sample input
$wholeContent =
[pscustomobject] @{ Name = 'Amma 10.0.0.1.zip'; Type = '...' },
[pscustomobject] @{ Name = 'Not a match' ; Type = '...' },
[pscustomobject] @{ Name = 'Amma 1.0.0.2.zip' ; Type = '...' },
[pscustomobject] @{ Name = 'Amma 2.1.2.3.zip' ; Type = '...' }
# Define the regex that matches the full name
# and captures the embedded version number in named capture group 'version'.
# Better to use '...' (single quotes) to define regexes, to prevent
# confusion with string expansion inside "..."
# Note the alternate syntax `<version>` instead of `'version'`.
$regex = '^Amma\s(?<version>(\d+\.){3}\d+)\.zip$'
# Filter by the line of interest, then sort by the extracted version number.
# Automatic variable $Matches is a hashtable that contains the results of
# the regex match, with entry 'version' containing the capture group's value.
# Casting to [version] ensures that version-appropriate sorting is used.
$wholeContent |
Where-Object { $_.Name -match $regex } |
Sort-Object { [version] ($_.Name -replace $regex, '${version}') }
Note that matching twice is required here[1]: once to filter in the lines of interest, and again to extract the embedded version text, via the -replace
operator.
Note: Use of -replace
with the original regex here is possible, because the regex at hand is designed to match the whole input string, which allows replacing the whole string with just the named capture group's value (${version}
) to yield only the latter; the more verbose alternative is to use another -match
operation to obtain the capture-group value via $Matches
:
$null = $_.Name -match $regex; $Matches['version']
The above yields the following, showing that only the lines of interest were extracted, properly sorted by version number:
Name Type
---- ----
Amma 1.0.0.2.zip ...
Amma 2.1.2.3.zip ...
Amma 10.0.0.1.zip ...
[1] While the automatic $Matches
variable, populated by a -match
operation, is available in script blocks in subsequent pipeline segments in principle, allowing access to the results of the matching operation, it cannot be utilized here, because Sort-Object
is of necessity an aggregating cmdlet; that is, it must collect all input first in order to perform sorting, at which point using $Matches
in the calculated property only contains the last input object's matches.