思った通りに sort されない (LC_COLLATE=en_US.UTF-8 の罠)
ls -l | sort したら、思った通りの順番に並ばないという相談を受けた。その方のLinux環境では、このように並ぶらしい。
一見して変だ。各行の先頭の文字は通常は - d t の順序(ASCIIコード順)に並ぶのだが、 これは d – t の順にならんでいる。 d t – でもないのが怪しさを増している。
[code lang="text"]
$ ls -l /var/log | sort
drwx—— 2 root root 4096 Jul 12 2021 private
drwxr-sr-x+ 2 root systemd-journal 4096 Jun 4 2021 journal
drwxr-x— 2 root adm 4096 Jul 22 2020 unattended-upgrades
drwxr-xr-x 2 landscape landscape 4096 Jul 12 2021 landscape
drwxr-xr-x 2 root root 4096 May 13 10:01 apt
drwxr-xr-x 2 root root 4096 May 14 2021 dist-upgrade
drwxr-xr-x 2 root root 4096 Nov 10 2020 gdm3
-rw——- 1 root root 0 Jul 12 2021 ubuntu-advantage.log
-rw——- 1 root root 0 Nov 5 2021 ubuntu-advantage-license-check.log
-rw——- 1 root root 0 Nov 5 2021 ubuntu-advantage-timer.log
-rw-r–r– 1 root root 1225679 May 13 10:02 dpkg.log
-rw-r–r– 1 root root 34006 May 13 09:39 alternatives.log
-rw-r–r– 1 root root 3835 Apr 25 21:00 fontconfig.log
-rw-r–r– 1 root root 9851 Jul 14 2021 Xorg.0.log
-rw-r–r– 1 root root 9851 Jul 14 2021 Xorg.0.log.old
-rw-rw—- 1 root utmp 0 Jun 4 2021 btmp
-rw-rw-r– 1 root utmp 292292 Apr 25 20:59 lastlog
-rw-rw-r– 1 root utmp 50688 Dec 10 01:23 wtmp
total 1644
[/code]
LC_COLLATEがen_US.UTF-8だと発生する
sortの順序なのだから、LC_COLLATEなのだろうと当たりをつけて調べてみると、私の環境でも LC_COLLATE=en_US.UTF-8 なら奇妙なsortになるようだ。なんだこれ。
よくよく調べてみると、en_USの場合は、辞書式順序で並び替えを行うらしい。 その場合、 ハイフン “-" を抜いた残りで並べ替えるようだ。なるほど確かに、先のsort結果は – を抜いてみると d r t の順に並んでいて正しいようだ。
英語版Wikipediaでも、スペースやハイフンを抜いて並べ替えるのを辞書式順(dictionary order)と呼んでいる。これが GNU sort で採用されている並べ替えの順序なのだろう。
When some of the strings being ordered consist of more than one word, i.e., they contain spaces or other separators such as hyphens, then two basic approaches may be taken. In the first approach, all strings are ordered initially according to their first word, as in the sequence:
Oak; Oak Hill; Oak Ridge; Oakley Park; Oakley River
where all strings beginning with the separate word Oak precede all those beginning Oakley, because Oak precedes Oakley in alphabetical order.
In the second approach, strings are alphabetized as if they had no spaces, giving the sequence:Oak; Oak Hill; Oakley Park; Oakley River; Oak Ridge
where Oak Ridge now comes after the Oakley strings, as it would if it were written “Oakridge".
The second approach is the one usually taken in dictionaries, and it is thus often called dictionary order by publishers. The first approach has often been used in book indexes, although each publisher traditionally set its own standards for which approach to use therein; there was no ISO standard for book indexes (ISO 999) before 1975.Alphabetical order – Wikipedia(強調は私による)
ちなみに、arch LinuxのWikiのロケールの項目には「潜在的な問題を回避するため、Arch では以前 /etc/profile で LC_COLLATE=C と設定していましたが、現在は使われなくなっています」と書かれている。
locale奥が深すぎる…
ディスカッション
コメント一覧
まだ、コメントがありません