关于PowerShell:更改排序对象行为

Alter Sort-Object behavior

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

为了说明问题:

1
2
3
4
5
6
PS > gci Z:\foo | sort -casesensitive
xyz
Xyz
XYZ
yZ
YZ

期望输出:

1
2
3
4
5
XYZ
Xyz
YZ
xyz
yZ

我尝试将当前线程的文化变量设置为[System.Globalization.CultureInfo]::InvariantCulture,但没有成功:

1
2
3
$thrd = [Threading.Thread]::CurrentThread
$thrd.CurrentCulture = [Globalization.CultureInfo]::InvariantCulture
$thrd.CurrentUICulture = $thrd.CurrentCulture

当我认为这与文化信息有关时,我是不是离目标更近?还是说我真的偏离了轨道?有人知道我该从哪里开始吗?我想我需要临时创建一个具有我想要的行为的CultureInfo实例,但它只具有CompareInfo所需的getter,更不用说我不确定如何重载CompareInfo.Compare函数,排序对象需要使用PowerShell函数。或者这实际上是一个失败的原因,因为那是不可能的?

编辑

至少,是否可以先用大写字符排序,如xyz、xyz、xyz、yz、yz?


我真的很努力地想找出是否有办法改变sort-object方法本身,但没有起作用。但是类似的事情,我可以使用StringComparer静态类完成,如这个msdn示例所示。

为了回答你的最后一部分,

1
At the very least, would it be possible to sort with uppercase characters first, as in XYZ, Xyz, xyz, YZ, yZ?

你的答案是。为了了解不同之处,我尝试了以下所有不同的版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
$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
#>