2013-03-01 72 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 
相關問題