改变排序对象行为 [英] Alter Sort-Object behavior

查看:33
本文介绍了改变排序对象行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用映射到 Linux 共享的驱动器时,文件名区分大小写.PowerShell 按预期处理此问题,但我想以类似于C"语言环境中使用的排序顺序的方式对输出进行排序,这意味着按字符值按升序排序,从 U+0000 一直到 U+10FFFF(例如'0foo'在'Foo'之前,'Foo'在'bar'之前,'bar'在'foo'之前)

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')

为了说明问题:

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

所需的输出:

XYZ
Xyz
YZ
xyz
yZ

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

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

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

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?

编辑

至少,是否可以先用大写字符进行排序,例如 XYZ、Xyz、xyz、YZ、yZ?

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

推荐答案

我真的很努力地想找到是否有办法改变 sort-object 方法本身,但没有工作.但是类似的事情我能够使用 StringComparer 静态类来完成,如本 msdn 示例.

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.

回答你的最后一部分,

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

[System.StringComparer]::InvariantCultureIgnoreCase 就是你的答案.为了查看差异,我尝试了以下所有不同版本.

[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
#>

这篇关于改变排序对象行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆