2013-03-01 74 views
3

我在尝试对大型CSV文件进行排序。问题是在名为Combined的coloum上使用sort-oject。它没有按我期望的方式排序!为了测试,我已经删除了所有未被排序的数据,并减少了行数。使用Powershell对CSV文件进行排序

原单CSV:

Combined 
1A THE BIG 
7 
3A SPRING 
19 
LUZREN 
21 
23 
25 
29 
1 HONEY 
5 
3 THE GOOD 
11 
ARVALA 
BRASAID 
13 
MEADOWCLAW 

PowerShell的:

Import-Csv orginal.csv -delimiter ',' | Sort-Object -Unique Combined 

Combined 
-------- 
1 HONEY 
11 
13 
19 
1A THE BIG 
21 
23 
25 
29 
3 THE GOOD 
3A SPRING 
5 
7 
ARVALA 
BRASAID 
LUZREN 
MEADOWCLAW 

我希望是这样的:

Combined 
1A THE BIG 
5 
7 
11 
13 
19 
21 
23 
25 
29 
1 HONEY 
3 THE GOOD 
3A SPRING 
ARVALA 
BRASAID 
LUZREN 
MEADOWCLAW 

在一个完美的世界,我想这样的:

Combined 
1A THE BIG 
1 HONEY 
3 THE GOOD 
3A SPRING 
5 
7 
11 
13 
19 
21 
23 
25 
29 
ARVALA 
BRASAID 
LUZREN 
MEADOWCLAW 

请有人向我解释为什么会发生这种情况我已经把我的头撞到我的显示器上一个星期了。另外,我怎么能得到我想要的输出?

非常感谢!

+0

默认排序是按符号的符号。 '1A THE BIG'如何在'1 HONEY'之前出现? – Aryadev 2013-03-01 13:12:50

+0

它将它们像字符串一样排序,这就是它应该如何工作的。如果你把每个数字像A之前的字母一样处理,它就像字母顺序排列一样完美。 – JNK 2013-03-01 13:14:51

回答

4

不知道我理解的排序逻辑,但试试这个:

$StartsWithNumber = { if ($_.Combined -match '^\d*\D') { $_.Combined } } 
$IsNumber = { if ($_.Combined -match '^\d*$') { [int]$_.Combined } } 
$OnlyLetters = { if ($_.Combined -imatch '^[a-z ]*$') { $_.Combined } } 

Import-Csv original.csv | 
Sort-Object $OnlyLetters, $IsNumber, $StartsWithNumber -Unique 

Combined 
-------- 
1 HONEY 
1A THE BIG 
3 THE GOOD 
3A SPRING 
5 
7 
11 
13 
19 
21 
23 
25 
29 
ARVALA 
BRASAID 
LUZREN 
MEADOWCLAW 
+1

+1我认为在$ startsWithNumer中的正则表达式更适合像这样的'^ \ d * \ D',以防某些值以多个单个数字开始。对? – 2013-03-01 14:34:54

+0

完美!我的完美世界输出是错误的(我的不好)。您的解决方案输出我所需要的。谢谢! – jetgerbil 2013-03-02 23:08:23

0

Import-CSV默认情况下导入所有值为string。这就是为什么你得到你看到的结果。它按字母顺序排序。字母数字中的“优先级”是:空格,数字,字母。

我不认为你可以得到你想要的输出没有一些严重的代码。我唯一的建议是将纯数字解析为int,如此。一批30会5之后这是可以做到这行:

$intvalue = 10000 
import-csv .\test.csv | % { 
    if ([int]::TryParse($_.Combined, [ref]$intvalue)) { 
     $_.Combined = $intvalue 
    } 
    $_ 
} | Sort-Object -Unique Combined 

Combined 
-------- 
1 HONEY 
5 
7 
11 
13 
19 
1A THE BIG 
21 
23 
25 
29 
3 THE GOOD 
3A SPRING 
ARVALA 
BRASAID 
LUZREN 
MEADOWCLAW 
1

试试这个:(而不是在完美的世界)

Import-Csv original.csv -delimiter ',' | 
Sort-Object { [int]([regex]::Replace($_.combined , "\D" , "")) } , ` 
{ [regex]::Replace($_.combined , "\d" , "") } -unique 

Combined 
-------- 
ARVALA 
BRASAID 
LUZREN 
MEADOWCLAW 
1 HONEY 
1A THE BIG 
3 THE GOOD 
3A SPRING 
5 
7 
11 
13 
19 
21 
23 
25 
29 

继@Aryadev的很好回答这个代码排序也值开始与一个以上的数字:

$allToNumbers = { [int]([regex]::Replace($_.combined , "\D" , "")) } 
$StartsWithNumber = { if ($_.Combined -match '^\d+\D') { $_.Combined } } 
$IsNumber = { if ($_.Combined -match '^\d*$') { [int]$_.Combined } } 
$OnlyLetters = { if ($_.Combined -imatch '^[a-z ]*$') { $_.Combined } } 

Import-Csv original.csv | 
Sort-Object $OnlyLetters, $allnumbers, $IsNumber, $StartsWithNumber -Unique 
相关问题