Sort

en_US.UTF-8 語言環境中的意外排序順序

  • June 11, 2020

在嘗試回答這個關於 SQL 排序的問題時,我注意到了一個sort我沒想到的順序:

$ export LC_ALL=en_US.UTF-8  
$ echo "T-700A Grouped" > sort.txt
$ echo "T-700 AGrouped" >> sort.txt
$ echo "T-700A Halved" >> sort.txt
$ echo "T-700 Whole" >> sort.txt
$ cat sort.txt | sort
T-700 AGrouped
T-700A Grouped
T-700A Halved
T-700 Whole
$ 

為什麼700 A排在上面700A,而排700A在上面700 W?我希望一個空格A始終出現在前面,獨立於它後面的字元。

如果您使用 C 語言環境,它可以正常工作:

$ export LC_ALL=C
$ echo "T-700A Grouped" > sort.txt
$ echo "T-700 AGrouped" >> sort.txt
$ echo "T-700A Halved" >> sort.txt
$ echo "T-700 Whole" >> sort.txt
$ cat sort.txt | sort
T-700 AGrouped
T-700 Whole
T-700A Grouped
T-700A Halved
$ 

排序是在多遍中完成的。每個角色都分配了三個(或有時更多)權重。假設對於這個例子,權重是

        wt#1 wt#2 wt#3
space = [0000.0020.0002]
A     = [1BC2.0020.0008]

為了創建排序鍵,將字元串中字元的非零權重連接起來,一次一個權重級別。也就是說,如果權重為零,則不添加相應的權重(如開頭所示" A")。所以

      wt#1   -- wt#2 ---   -- wt#3 ---
" A" = 1BC2   0020   0020   0002   0008
      A      sp     A      sp     A

      wt#1   wt#2   wt#3
"A"  = 1BC2   0020   0008
      A      A      A

      wt#1   -- wt#2 ---   -- wt#3 ---
"A " = 1BC2   0020   0020   0008   0002
      A      A      sp     A      sp

如果你對這些數組進行排序,你會得到你看到的順序:

      1BC2   0020   0008               => "A"
      1BC2   0020   0020   0002   0008 => " A"
      1BC2   0020   0020   0008   0002 => "A "

這是對實際發生的事情的簡化;有關更多詳細資訊,請參閱Unicode 排序算法。上面的範例權重實際上來自標準表,省略了一些細節。

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