在PowerShell中自定义排序
问题描述:
我是电源外壳的新手。在PowerShell中自定义排序
我的问题是,我在下面的格式文件名:
[ignore-prefix]-[important-middle]-[ignore-suffix]-[name-with-digits]
我需要按照以下规则进行排序:首先按名称由中间部分,然后,以自然顺序(即foobar10> foobar2) 。我不知道前缀值,但我知道分隔符(破折号)。
所以我的第一次尝试,自然:
filelist | Sort-Object -property @{Expression=`
{$_.FullName.SubString($_.FullName.IndexOf("-")+1)}}
这有后缀影响顺序(忽略-AAA-1ignore-wname)忽略-AAA-2ignore-aname),所以之前排序的问题:
$filelist | Sort-Object -property @{Expression=`
{$_.FullName.SubString($_.FullName.IndexOf("-")+1,`
$_.FullName.SubString($_.FullName.IndexOf("-")+1).IndexOf("-"))}}
好吧,那种在中间,但已经不笨。如果我要添加更糟糕的自然排序。什么更优雅的方式来做到这一点?
答
我以这种方式理解任务:排序应该由3个表达式来执行:1)中间部分,2)没有数字的名称部分,3)名称部分的尾部数字所表示的数字。
让我们用正则表达式创建这些表达式。下面是答案:
# gets the middle part
$part1 = { if ($_.Name -match '^[^-]+-([^-]+)') { $matches[1] } }
# gets the name part with no digits
$part2 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-(\D+)') { $matches[1] } }
# gets the number represented by digits from name (cast to [int]!)
$part3 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-\D+(\d+)') { [int]$matches[1] } }
# sort it by 3 expressions
$filelist | Sort-Object $part1, $part2, $part3
为了更好地理解它是如何运作的,你可以分别测试这些表达式:
$part1 = { if ($_.Name -match '^[^-]+-([^-]+)') { $matches[1] } }
$part2 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-(\D+)') { $matches[1] } }
$part3 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-\D+(\d+)') { [int]$matches[1] } }
Write-Host '----- test1'
$filelist | % $part1
Write-Host '----- test2'
$filelist | % $part2
Write-Host '----- test3'
$filelist | % $part3
结果,例如,这些文件(扩展名并不重要):
aaa-zzz-1ignore-wname10.txt
aaa-zzz-1ignore-wname2.txt
ignore-aaa-1ignore-wname10.txt
ignore-aaa-1ignore-wname2.txt
进行排序,如:
ignore-aaa-1ignore-wname2.txt
ignore-aaa-1ignore-wname10.txt
aaa-zzz-1ignore-wname2.txt
aaa-zzz-1ignore-wname10.txt
“$ part1,$ part2,$ part2”应该是“$ part1,$ part2,$ part3” 谢谢! – DennyRolling 2010-11-10 17:27:51
是的,我也注意到了。固定。 – 2010-11-10 17:30:37