Powershell 改变排序对象行为

Powershell 改变排序对象行为,powershell,powershell-2.0,Powershell,Powershell 2.0,使用映射到Linux共享的驱动器时,文件名区分大小写。PowerShell按预期处理此问题,但我希望以类似于“C”区域设置中使用的排序顺序的方式对输出进行排序,这意味着从U+0000一直到U+10FFFF(例如,“0foo”位于“Foo”之前,“Foo”位于“bar”之前,“bar”位于“Foo”之前) 为了说明这个问题: PS > gci Z:\foo | sort -casesensitive xyz Xyz XYZ yZ YZ 所需输出: XYZ Xyz YZ xyz yZ 我尝

使用映射到Linux共享的驱动器时,文件名区分大小写。PowerShell按预期处理此问题,但我希望以类似于“C”区域设置中使用的排序顺序的方式对输出进行排序,这意味着从U+0000一直到U+10FFFF(例如,“0foo”位于“Foo”之前,“Foo”位于“bar”之前,“bar”位于“Foo”之前)

为了说明这个问题:

PS > gci Z:\foo | sort -casesensitive
xyz
Xyz
XYZ
yZ
YZ
所需输出:

XYZ
Xyz
YZ
xyz
yZ
我尝试将当前线程的区域性变量设置为
[System.Globalization.CultureInfo]::InvariantCulture
,但没有成功:

$thrd = [Threading.Thread]::CurrentThread
$thrd.CurrentCulture = [Globalization.CultureInfo]::InvariantCulture
$thrd.CurrentUICulture = $thrd.CurrentCulture
当我认为这与文化信息有关时,我是否已经接近了,或者我真的偏离了轨道?有人知道我该从哪里开始吗?我猜我需要临时创建一个CultureInfo实例,该实例具有我想要的行为,但它只有CompareInfo的getter,更不用说我不确定如何重载CompareInfo.Compare函数,排序对象需要使用PowerShell函数。或者这实际上是一个失败的原因,因为这是不可能的

编辑


至少,是否可以先使用大写字符进行排序,如在XYZ、XYZ、XYZ、YZ、YZ中?

我非常努力地寻找是否有办法改变
排序对象
方法本身,但不起作用。但是,正如本文所示,我可以使用StringComparer静态类实现类似的功能

为了回答你的最后一部分

At the very least, would it be possible to sort with uppercase characters first, as in XYZ, Xyz, xyz, YZ, yZ?
[System.StringComparer]::不变量文化识别码是您的答案。为了了解差异,我尝试了下面所有不同的版本

$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
#>
$arr=“0foo”、“xyz”、“xyz”、“YZ”、“YZ”、“xyz”、“Foo”、“bar”
$list=新对象System.Collections.ArrayList
$list.AddRange($arr)
写入主机“CurrentCulture”
$list.Sort([System.StringComparer]::CurrentCulture);
美元清单
写入主机“CurrentCultureIgnoreCase”
$list.Sort([System.StringComparer]::currentCultureInogoreCase);
美元清单
编写主机“不变量文化”
$list.Sort([System.StringComparer]::InvariantCulture);
美元清单
编写主机“不变量文化识别码”
$list.Sort([System.StringComparer]::InvariantCultureInogoreCase);
美元清单
写主机“序号”
$list.Sort([System.StringComparer]::序号);
美元清单
写入主机“OrdinalIgnoreCase”
$list.Sort([System.StringComparer]::OrdinalIgnoreCase);
美元清单

非常彻底。我希望我不需要做这样的事情,但显然排序的想法相当有限,即使在PowerShell中也是如此。非常感谢。'Ordinal'是.NET中的比较,它根据字符的代码点值对字符进行比较(另请参见)。看起来是最好的选择。