- 写真ファイルを アルファベット順に並べようとしたところ、OSとファイルマネージャーで並び順の結果が異なっていた
- Linux の
ls では正常に並ぶ一方、Windows、Google Drive、KDE Dolphin など大半の GUI ファイルマネージャーは、数字を含むファイル名に 数値として解釈する「ナチュラルソート(natural sort)」 を適用する
- そのため
file-10.txt が file-9.txt より前に来るなど、従来の文字列ソートとは異なる結果が生じる
- 実際の原因は、2台のスマートフォンが異なるファイル名規則を使っており、一方は 秒の後にミリ秒 をそのまま連結し、もう一方は アンダースコアで区切っていた ため、ソート基準が変わっていたこと
- 結局の解決策は、ファイル名規則を統一するか、各ファイルマネージャーの隠れた設定を変更する しかなく、筆者は「コンピューターがユーザーの指示より推測を優先する時代」を惜しんでいる
背景と問題の状況
- 筆者は父親とハイキングをした際、それぞれの Android スマートフォンで写真を撮り、すべての写真を1つのフォルダに保存した
- 写真のファイル名規則は
IMG_YYYYMMDD_HHmmss、またはその後ろに追加の数字と .jpg が付く形式
- この種のファイル名は年月日と時刻の順に並んでいるため、ファイルを アルファベット順(辞書順)に並べれば撮影時刻順に並ぶはずだと考えた
- ところが Windows PC、Google Drive、KDE Dolphin などを使うと、同じ規則のファイルが順番どおりに並ばない
- 例: 父親のスマートフォンで撮られた 5:54 の写真が 9:20 の写真より先に出たり、12:11 の写真より後ろに置かれたりするなど、正しく並ばない問題が発生
- Gnome やスマートフォン上の別のファイルマネージャーでも結果は同じだった
- Linux の
ls コマンドでは正しい順序が保たれ、混乱が深まった
原因分析
- 当初は、2台のスマートフォンのどちらかが アンダースコア(_)の代わりに変わった文字を使っているのでは と考えたが、Linux コマンドの
ls で確認すると正常に並んでいた
- さまざまな Linux ディストリビューションや OpenBSD サーバーでも、ls は正しくアルファベット順にソートした
- これに対して、多くの GUI ファイルマネージャー(Windows、Google Drive、KDE Dolphin など)は、ファイル名に数字があると実際の数の大きさ で比較する
- アルファベット順ではなくナチュラルソート(natural sorting) をデフォルトで適用する
- ナチュラルソートでは、文字列中の数字を単なる文字コード値ではなく 数値 として比較する
- 例:
file-9.txt < file-10.txt → 人が期待する順序
- しかし従来のソートでは
1 < 9 のため、file-10.txt が前に来る
- ところが最近のファイルマネージャーは、「数字の部分」があると その部分を数値の実際の値として解釈し、9 が 10 より前に来るよう強制的に並べる
- ファイル名を付けたユーザーが意図した順序と異なる可能性がある
実際の原因と解決法
- 父親のスマートフォンはミリ秒の数字を秒の直後にそのまま付け、筆者のスマートフォンは アンダースコアで区切って表記していた
- 父親のスマートフォン: 秒の後ろにそのままミリ秒を付加 → 数字が大きくなり後ろへ回る
- 筆者のスマートフォン: アンダースコアで区切る → 別の文字列として扱われる
- 解決法: どちらか一方のファイル名を一貫したパターンにそろえて並べ直す と問題は解消した
- KDE Dolphin ではオプションで純粋なアルファベット順ソートを選べるが、設定が隠れていて面倒
- プログラムごとに機能が異なるため、その都度別々に設定が必要になる場合がある
筆者の結論
- 「アルファベット順」を指定したにもかかわらず、ソフトウェアがユーザーの意図を推測して別のソートを適用する ことを批判
- かつてのように コンピューターが指示されたとおりにだけ動いていた単純な方式 が恋しい
1件のコメント
Hacker Newsの意見
Microsoft、Google、KDEが採用している並べ替え方式のほうが、より直感的で一般的によくあるケースをカバーしていると思う、投稿者のケースはきわめてまれだと判断する、ほとんどの人は「10」が「9」の次に来てほしい場面のほうがずっと多いと感じる、デスクトップ環境では並べ替えを「アルファベット順」ではなく「名前順」と表記しているので誤解はない、コンピュータが意図を読もうとするのは好きではないが、自動保存のような機能と同じでそういうものは実生活で役に立つ、本当のアルファベット順ソートのオプションもあればよいが、デフォルトは一般的なケースで直感的なものが適切だ
この話題は「Worse is better」論争を思い出させる、投稿者が求めている ANSI/Unicode ベースの単純なソート方式は、むしろ少数の開発者だけが必要とする機能だ、実際には GUI 利用者の 99% は直感的な並べ替えを望んでいる、主な利用者を把握することが製品設計に非常に大きな影響を与える、よりよい機能は製品には合うかもしれないが、システムには成長と進化のための単純さのほうが合うこともある
ハッシュ値で名前を付けたファイルを探すとき、自動ソートがいちばん不便だ、Windows ではレジストリですぐ無効にする数少ない設定の 1 つだ、昔のようにコンピュータが言われた通りにだけ動いていた時代が恋しいと思うことがよくある、最近は「ユーザーの気持ちを読む」のではなく「考えまで変えようとしてくる」ようで嫌だ、オープンソースも含めて「ユーザーが間違っている」という独善的なマインドには不満がある
みなが平均的なユーザーのニーズを知っていると主張するなら、なぜ肝心のコンピュータにファイル名そのものを望む通りに自動で変えさせようという意見は出ないのかと疑問に思う、ASCII ソートを強制しないなら拡張子を含むファイル名にこだわる必要もない、実際のところユーザーは jpg や png の拡張子を重視せず、大文字小文字の区別も気にしない、Windows 系でだけ古い互換性のために拡張子が多用されてきた、「コンピュータ的なファイル名」は強制するのに、なぜ「コンピュータ的なソート」だけ頑固に壊すのか不思議だ、ユーザーが何を望むかはわからないのだから決めつけるべきではない
私はたいてい、今記事で説明されているバージョンベースの並べ替えのほうがよいと感じる、アルファベット順ソートで表示されるほうがバグのように感じるくらいだ、問題はソートの概念ではなくラベリングだと思う
sortコマンドも現在はバージョンソート(sort -V)をサポートしている、内部動作はよくわからないが、ほとんどの状況でうまく動く、何より簡単に on/off できるファイルを「アルファベット順」に並べろと命令しているのではなく「名前順」ソートを求めているのだから、解釈は OS ごとに異なりうる、ほとんどのユーザーにとってより適切な解釈を論理とデータに基づいて選んだのだと思う、おそらく将来は数字グループに 0 があれば元のアルファベット順を使うといったルールが追加されたり、ユーザー選択オプションが生まれたりするかもしれない
macOS Foundation では Finder の並べ替えに使われる
NSString.localizedStandardCompare()を公式に提供している、Windows もStrCompareLogicalを提供している、つまり名前順(つまり自然順ソート)の基準を各プラットフォームで公式化しているlsコマンドと違うとは思っていたので興味深かったし、今ではこの方式のほうがよいと思うようになった、写真アプリでは一般にタイムスタンプで並べ替えるし、ファイルで本当に名前順ソートが必要なら作成日で並べ替えるか、いっそファイル名を自分で正規化するだろうUnicode レポートでは、言語ごとに文脈に応じて並べ替え方式が変わることを明確に述べている、例: "A-10" を数字として認識せずアルファベット順に並べると「A-10」が「A-2」より前に来る、複雑ではあるが、ファイルブラウザがこうした理由で自然順ソート方式を採用したのは正しいと思う
「foo9」が「foo10」より前に来るように並べるのが「natural sort」だ、最近 Python 2 行のコードで自然順ソートの方法を知り、とても満足している、関連 Stack Overflow のコード をおすすめする
sort(1)コマンドでも自然順ソート(-V)をサポートしている、画像ファイルを作ってls | sort -Vで並べればきちんと動く、du -sh *の結果もsort -hオプションで並べ替え可能だ「Image-1.jpg, Image-11.jpg, Image-2.jpg」のように混ざる並べ替え方式は恋しくない、自然順ソートが不自然に感じられた記憶もあるが、Windows で数値として並べ替えるように変わって本当に便利になった、ファイルが自然に並ぶようになってかなり満足した