问题
When working with a drive mapped to a Linux share, filenames are case sensitive. PowerShell handles this as expected, but I'd like to sort the output in a manner analogous to the sort order used in the "C" locale, which means sorting by character value in ascending order from U+0000 all the way through U+10FFFF (e.g. '0foo' comes before 'Foo' and 'Foo' comes before 'bar' and 'bar' comes before 'foo')
To illustrate the problem:
PS > gci Z:\foo | sort -casesensitive
xyz
Xyz
XYZ
yZ
YZ
Output desired:
XYZ
Xyz
YZ
xyz
yZ
I tried setting the current thread's culture variables to [System.Globalization.CultureInfo]::InvariantCulture, but I had no success:
$thrd = [Threading.Thread]::CurrentThread
$thrd.CurrentCulture = [Globalization.CultureInfo]::InvariantCulture
$thrd.CurrentUICulture = $thrd.CurrentCulture
Am I even close when I assume it has to do with the culture info, or am I really far off track? Does anybody have any idea where I should start? I'm guessing I need to temporarily create a CultureInfo instance that has the behavior I desire, but it only has getters as far as CompareInfo goes, not to mention I'm unsure of how to overload the CompareInfo.Compare function that Sort-Object requires using PowerShell functions. Or is this effectively a lost cause because that isn't possible?
Edit
At the very least, would it be possible to sort with uppercase characters first, as in XYZ, Xyz, xyz, YZ, yZ?
回答1:
I tried really hard to find if there is a way to alter the sort-object method itself but not working. But something similar I was able to accomplish using StringComparer static class as demonstrated in this msdn example.
To answer your last part,
At the very least, would it be possible to sort with uppercase characters first, as in XYZ, Xyz, xyz, YZ, yZ?
[System.StringComparer]::InvariantCultureIgnoreCase is your answer. To see the differences I have tried all the different versions below.
$arr = "0foo","xyz","Xyz","YZ","yZ","XYZ","Foo","bar"
$list = New-Object System.Collections.ArrayList
$list.AddRange($arr)
Write-host "CurrentCulture"
$list.Sort([System.StringComparer]::CurrentCulture);
$list
<# --------CurrentCulture--------
CurrentCulture
0foo
bar
Foo
xyz
Xyz
XYZ
yZ
YZ
#>
Write-Host "CurrentCultureIgnoreCase"
$list.Sort([System.StringComparer]::CurrentCultureIgnoreCase);
$list
<# --------CurrentCultureIgnoreCase--------
CurrentCultureIgnoreCase
0foo
bar
Foo
XYZ
Xyz
xyz
YZ
yZ
#>
Write-Host "InvariantCulture"
$list.Sort([System.StringComparer]::InvariantCulture);
$list
<# --------InvariantCulture--------
InvariantCulture
0foo
bar
Foo
xyz
Xyz
XYZ
yZ
YZ
#>
Write-Host "InvariantCultureIgnoreCase"
$list.Sort([System.StringComparer]::InvariantCultureIgnoreCase);
$list
<# --------InvariantCultureIgnoreCase--------
InvariantCultureIgnoreCase
0foo
bar
Foo
XYZ
Xyz
xyz
YZ
yZ
#>
Write-Host "Ordinal"
$list.Sort([System.StringComparer]::Ordinal);
$list
<# --------Ordinal--------
Ordinal
0foo
Foo
XYZ
Xyz
YZ
bar
xyz
yZ
#>
Write-Host "OrdinalIgnoreCase"
$list.Sort([System.StringComparer]::OrdinalIgnoreCase);
$list
<# --------OrdinalIgnoreCase--------
OrdinalIgnoreCase
0foo
bar
Foo
xyz
XYZ
Xyz
yZ
YZ
#>
来源:https://stackoverflow.com/questions/18543842/alter-sort-object-behavior