數字排序
我有一個名為的文件
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
要放在數字之間?怎麼比它們10
大9
,但又比它們小6
,11
又比它們都大?
-g
似乎可以按我的意願工作(並且我認為是自然的),但是這個選項-n
完全讓我無法理解。這是怎麼回事?我認為它可能與語言環境有關,但是一旦我將分隔符指定為 is,
,我認為這不會解釋它。
TL;博士
使用
sort -nk1,1 -t,
或以其他方式-k1
對整行進行排序,其中,
數字被丟棄,因為它被解釋為千位分隔符。細節
在英語語言環境中,
,
是千位分隔符,它sort
忽略了數字的整數部分。換句話說,在英語語言環境中,或任何
,
有千位分隔符的語言環境中(參見 的輸出locale thousands_sep
),當sort -n
看到11,000,000
它時,它不會看到11
數字後面跟著一些被忽略的垃圾,而是11000000
數字。同樣11,0
is not11
but110
。現在(這是很多人的絆腳石),
-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
所以不是
6
vs10
vs11
,而是61.4433853830416671
vs10
vs110.5923834706792905
。在這裡,你想要:
sort -nk1,1 -t,
僅對第一個
,
分隔欄位進行排序。-k1,1
定義一個排序鍵,從第一個欄位的開頭開始,到第一個欄位的結尾結束。您也可以
sort -n
在 C 語言環境中使用,其中,
既不是十進制基數也不是千位分隔符(並且.
是十進制基數):LC_ALL=C sort -n
sort -g
工作方式不同,因為sort
then 用於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