Sort

排序不使用管道“|”對行進行排序正確地在其中

  • December 12, 2018

我正在嘗試對一些簡單的管道分隔數據進行排序。但是,排序實際上並不是排序。它將我的標題行移動到底部,但是我以 241 開頭的兩行被以 24 開頭的行分開。

cat sort_fail.csv
column_a|column_b|column_c
241|212|20810378
24|121|2810172
241|213|20810376

sort sort_fail.csv
241|212|20810378
24|121|2810172
241|213|20810376
column_a|column_b|column_c

列標題被移到文件的底部,因此 sort 顯然正在處理它。但是,實際值並沒有像我期望的那樣排序。

在這種情況下,我解決了它

sort sort_fail.csv --field-separator='|' -k1,1

但是,我覺得這不應該是必要的。為什麼排序不排序?

sort是區域設置感知的,因此根據您的 LC_COLLATE 設置(從 LANG 繼承),您可能會得到不同的結果:

$ LANG=C sort sort_fail.csv 
241|212|20810378
241|213|20810376
24|121|2810172
column_a|column_b|column_c

$ LANG=en_US sort sort_fail.csv
241|212|20810378
24|121|2810172
241|213|20810376
column_a|column_b|column_c

這可能會導致腳本出現問題,因為您可能不知道呼叫區域設置為什麼,因此可能會得到不同的結果。

腳本強制設置所需的設置並不少見

例如

$ grep 'LC.*sort' /bin/precat
     LC_COLLATE=C sort -u | prezip-bin -z "$cmd: $2"

現在有趣的是,這個|角色看起來很奇怪。

但這是因為源自 ISO 的 en_US 的預設規則說

$ grep 007C /usr/share/i18n/locales/iso14651_t1_common
<U007C> IGNORE;IGNORE;IGNORE;<j> # 142 |

這意味著該|字元被忽略並且排序順序就像該字元不存在一樣..

$ tr -d '|' < sort_fail.csv | LANG=C sort
24121220810378
241212810172
24121320810376
column_acolumn_bcolumn_c

這與您看到的“意外”排序相匹配。

解決方法是使用-n(強制數字排序),或使用欄位分隔符(如您所做的那樣)或使用C語言環境。

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