2012-07-12 37 views
5

我需要與UNIX排序一些數據進行排序,但我不完全正確的語法,數據的模樣UNIX排序爲2場數字順序

3.9.1 Step 10: 
3.9.1 Step 20: 
3.8.10 Step 20: 
3.10.2 Step 10: 
3.8.4 Step 90: 
3.8.4 Step 100: 
3.8.4 Step 10: 

我想對它進行排序首先使用的主要數字,然後是步數,例如上面分類的數據看起來像。

3.8.4 Step 10: 
3.8.4 Step 90: 
3.8.4 Step 100: 
3.8.10 Step 20: 
3.9.1 Step 10: 
3.9.1 Step 20: 
3.10.2 Step 10: 

我發現通過第一個號碼本網站的排序方法:

sort -t. -k 1,1n -k 2,2n -k 3,3n 

但我不打擾第一個排序

+0

當我嘗試你給你的樣本數據的命令行,它產生的答案你說你想... – jacobm 2012-07-12 01:42:21

+0

@jacobm,重新檢查第3列,它的排序錯誤 – Steve 2012-07-12 01:45:50

+0

我在solaris 10,如果這有所作爲,是啊第三列仍然不正確 – jdex 2012-07-12 01:48:30

回答

2

關於重新設計Unix sort('工作分類例程構建中的理論和實踐',JP Linderman,AT & T Bell Labs Tech Journal,Oct 1984),有一篇非常吸引人的文章,這不幸的是,它不能在互聯網上使用,AFAICT(我看了大約一年前,並沒有找到它;我剛纔看了一遍,可以找到它的參考,但不是文章本身)。除此之外,該文章還表明,對於Unix sort,比較時間遠遠超過移動數據的成本(當您認爲比較必須比較每行所確定的字段時,這並不令人驚訝,但移動「數據」僅僅是一個問題切換指針周圍)。其中一個結果是,他們建議做什麼danfuzz建議;映射鍵以便比較容易。他們表明,即使一個簡單的腳本解決方案可以節省時間相比,真正艱難的排序工作。

因此,您可以考慮使用不太可能出現在數據文件中的字符(例如Control-A)作爲關鍵字段分隔符。

sed 's/^\([^.]*\)[.]\([^.]*\)[.]\([^ ]*\) Step \([0-9]*\):.*/\1^A\2^A\3^A\4^A&/' file | 
sort -t'^A' -k1,1n -k2,2n -k3,3n -k4,4n | 
sed 's/^.*^A//' 

第一個命令是困難的。它標識4個數字字段,並將它們以選定字符(上面編寫的^A,輸入爲Control-A)分隔輸出,然後輸出原始行的副本。然後該排序在前四個字段上進行數字化處理,並且最後的sed命令從每行的前面剝去直到幷包括最後一個Control-A,再次給出原始行。

+0

有關的其他方式? http://cs.fit.edu/~pkc/classes/writing/samples/bentley93engineering.pdf – 2012-07-12 23:20:27

+0

@FrankComputer:相關的,絕對 - 它引用了Linderman。但不是一回事。另請參閱[爲快速排序選擇數據透視表](http://stackoverflow.com/questions/164163/choosing-a-pivot-for-quicksort/164183#164183),其中提到了您所詢問的賓利紙,以及一些其他。 – 2012-07-12 23:40:26

+0

能夠在這裏得到一個簡短的預覽:http://books.google.com/books?id=Hy62AAAAIAAJ&q=Linderman#search_anchor – 2012-07-12 23:54:25

2

掙扎到現在排序第3列步驟數如何將Step:轉換成sort,然後再轉換回來?我相信這可以讓你要尋找的結果:(只需使用cat這裏說明的目的如果只是一個普通的文件,那麼它可以被傳遞到第一sed

cat your-file.txt \ 
    | sed -e 's/ Step \(.*\):$/.\1/g' \ 
    | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n \ 
    | sed -e 's/\(.*\)\.\(.*\)$/\1 Step \2:/g' 

+0

我一直希望只使用排序的整潔的解決方案,但我想這也可以。 +1會看到其他人是否知道與 – jdex 2012-07-12 03:30:40

1

修訂

這將生成您指定的輸出:

sed 's/Step /Step./' data|sort -t. -n -k1,1 -k2,2 -k3,3 -k4|sed 's/Step./Step /' 

結果:

3.8.4 Step 10: 
3.8.4 Step 90: 
3.8.4 Step 100: 
3.8.10 Step 20: 
3.9.1 Step 10: 
3.9.1 Step 20: 
3.10.2 Step 10: 

有了這樣的挑戰是,在排序字段定義由'.'(用於版本號)和d默認空格(用於步驟編號)。您不能爲相同的排序命令指定多個/不同的字段分隔符。將幾種不同的字段分隔符組合在一起不會產生正確的輸出。

此解決方案由Step字段暫時'.'使得所有排序字段可以用相同的字符('.')分離後更換空白空間。排序完成後,'.'將被替換爲空白。

+0

它沒有按步驟列排序雖然.. – jdex 2012-07-12 03:31:28

+0

@jdex我找到了一個我相信的解決方案,請查看這是否是您的問題的可接受答案。 – Levon 2012-07-12 11:50:03

+0

+ 1,我真的很想避免修改數據,因爲我提供的不是完整的數據集。每個步驟都有一個字符串描述(有時也包含「Step」)。它開始看起來像沒有其他方式雖然 – jdex 2012-07-13 00:05:05

2

這可能會爲你工作:

sort -k3,3n file | sort -nst. -k1,1 -k2,2 -k3,3 

還是很玄乎:按步驟

  • sort -nst. -k1,1 -k2,2 -k3,3各種

    1. sort -k3,3n類:

      sort -nt. -k1,1 -k2,2 -k3,3 -k3.7 file 
      

      第一種使用兩類由主要數字,但保持步驟或明鏡

    第二個作品,但只有在第3主號碼仍低於100

    或者是:

    sed 's/ /./2' file | sort -nt. -k1,1 -k2,2 -k3,3 -k4,4 | sed 's/\./ /3' 
    
  • +0

    我認爲第一個可以工作,但是我在solaris 10上使用的排序版本沒有-s選項。 – jdex 2012-07-12 23:34:50

    +0

    @jdex對不起,我猜'-s'是一個GNU功能。 'sed'解決方案可能會有所幫助 – potong 2012-07-13 00:00:28