Sort

數字排序

  • April 15, 2019

我有一個名為的文件data,其內容是

id,col1,col2
0,-0.3479417882673812,0.5664382596767175
1,-0.26800930980980764,0.2952025161991604
2,-0.4159790791116641,-1.3375045524610152
3,-0.7859665489205871,-0.6428101880909471
4,-1.3922759043388822,-1.676262144826317
5,-1.2471867496427498,-0.4912119581361516
6,1.443385383041667,1.6974039491263593
7,-2.058899802821969,2.0607628464079917
8,-0.10641338441541626,0.035929568275064216
9,-0.517273684861199,-0.6184800988804992
10,-0.9934859021679552,1.0577312348984502
11,0.5923834706792905,-0.6693757541250825
12,0.8657741917554445,-0.6876271057571398
13,-1.2061097548360489,-0.7402582563022937
14,0.78768021182158,-0.38607117005262315

-n對第一列進行數字排序 ( ) 給出

$ sort -nk1 -t"," data
0,-0.3479417882673812,0.5664382596767175
id,col1,col2
1,-0.26800930980980764,0.2952025161991604
2,-0.4159790791116641,-1.3375045524610152
3,-0.7859665489205871,-0.6428101880909471
4,-1.3922759043388822,-1.676262144826317
5,-1.2471867496427498,-0.4912119581361516
7,-2.058899802821969,2.0607628464079917
8,-0.10641338441541626,0.035929568275064216
9,-0.517273684861199,-0.6184800988804992
10,-0.9934859021679552,1.0577312348984502
13,-1.2061097548360489,-0.7402582563022937
6,1.443385383041667,1.6974039491263593
11,0.5923834706792905,-0.6693757541250825
12,0.8657741917554445,-0.6876271057571398
14,0.78768021182158,-0.38607117005262315

這對我來說絕對是奇怪的。我在手冊頁中讀到了-n應該是數字排序的。為什麼id要放在數字之間?怎麼比它們109,但又比它們小611又比它們都大?

-g似乎可以按我的意願工作(並且我認為是自然的),但是這個選項-n完全讓我無法理解。這是怎麼回事?我認為它可能與語言環境有關,但是一旦我將分隔符指定為 is ,,我認為這不會解釋它。

TL;博士

使用sort -nk1,1 -t,或以其他方式-k1對整行進行排序,其中,數字被丟棄,因為它被解釋為千位分隔符。

細節

在英語語言環境中,,是千位分隔符,它sort忽略了數字的整數部分。

換句話說,在英語語言環境中,或任何,有千位分隔符的語言環境中(參見 的輸出locale thousands_sep),當sort -n看到11,000,000它時,它不會看到11數字後面跟著一些被忽略的垃圾,而是11000000數字。同樣11,0is not 11but 110

現在(這是很多人的絆腳石),-k1定義了一個從第一個欄位開始的鍵,但由於您沒有指定它在哪裡停止,在行尾結束,所以排序鍵是整行,它是預設值。

所以sort -nk1 -t,是完全一樣的sort -n

,忽略千位分隔符,您的輸入sort實際上是對這些數字進行排序:

0
1
2
3
4
5
61.4433853830416671
7
8
9
10
110.5923834706792905
120.8657741917554445
13
140.78768021182158

所以不是6vs 10vs 11,而是61.4433853830416671vs 10vs 110.5923834706792905

在這裡,你想要:

sort -nk1,1 -t,

僅對第一個,分隔欄位進行排序。-k1,1定義一個排序鍵,從第一個欄位的開頭開始,到第一個欄位的結尾結束。

您也可以sort -n在 C 語言環境中使用,其中,既不是十進制基數也不是千位分隔符(並且.是十進制基數):

LC_ALL=C sort -n

sort -g工作方式不同,因為sortthen 用於strtold()將鍵解釋為數字並且strtold()不辨識千位分隔符。

id標題行而言,在數字比較中,這id...被解釋為0那裡沒有數字。它在開頭的行之後排序,0因為當兩個記錄排序相同時(這裡-n是數字比較)sort最後的比較是對整行的詞法0比較(並且在之前排序i)。

在某些sort實現中,最後的比較可以用-s. 這裡LC_ALL=C sort -sn將把該id行放在第一位,但這只是因為輸入中沒有否定鍵(id(數字再次為 0)仍然會排在 之後-1)。如果要從排序中排除第一行,可以執行以下操作:

(head -n1; LC_ALL=C sort -n) < file

引用自:https://unix.stackexchange.com/questions/512596