lsが結果をこのようにソートするのはなぜですか? [コピー]

lsが結果をこのようにソートするのはなぜですか? [コピー]

ls出力が次のようにソートされる理由を知りたいです。

$ mkdir SortTest<br>
$ cd SortTest<br>
$ for a in {1..34}; do touch filename_$a.txt; done
$ ls -l
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_10.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_11.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_12.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_13.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_14.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_15.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_16.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_17.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_18.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_19.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_1.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_20.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_21.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_22.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_23.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_24.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_25.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_26.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_27.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_28.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_29.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_2.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_30.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_31.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_32.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_33.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_34.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_3.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_4.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_5.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_6.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_7.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_8.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_9.txt

別の議論では、ls -vがより有用なアプローチを提供することがわかりました。ただし、これはパラメータなしで予想される出力を変更しません。つまり、

(何を期待したのに、どのように動作しないのでしょうか?ところでなぜそうでしょうか?)

-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_1.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_10.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_11.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_12.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_13.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_14.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_15.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_16.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_17.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_18.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_19.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_2.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_20.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_21.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_22.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_23.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_24.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_25.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_26.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_27.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_28.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_29.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_3.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_30.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_31.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_32.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_33.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_34.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_4.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_5.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_6.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_7.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_8.txt
-rw-r--r-- 1 user user 0 Jun 28 10:49 filename_9.txt

ASCIIテーブルでは、ドット「.」が0..9の前にあることを願っています。ソートでは、デフォルトのファイル名と拡張子を別々に処理する必要がありますが、filename_1はfilename_10より短いので、ソートされた文字列テーブルに最初に表示する必要があります。

それでは... lsはなぜこれらすべてを無視し、filename_10.txtの後にfilename_1.txtをfilename_19.txtとして返しますか?

知っている人はいますか?そして…いつもそうでしたか、それともこれが現代の「改善事項」の一つですか?後者なら簡単にドラッグできますか?それとも実際にはPOSIX(または他の標準)の要件ですか?

個人的には、私は単純なルールに従わないコンピュータが好きではありませんが、何人かの人々はこれが「よりユーザーフレンドリー」であると思っていますが、最終的には驚くべきコンピュータが好きではありません。

$ ls --version
ls (GNU coreutils) 8.30

答え1

返信ありがとうございます。有用な説明を提供しました。

私が正しく理解した場合:

最新のシステムは言語固有のロケールを持つ傾向があります。手動でLC_COLLATE = Cに設定していない場合は、LC_COLLATEに従ってください。

ただし、これにより、大文字/小文字のアルファベット文字が言語固有の「自然な」方法で処理されるようにソート順序が変更されるだけでなく、ソート時に句読点も無視されます。

したがって、filename_1.txt は filename_1txt のようにソートされ、filename_19txt の後に表示されます。

個人的には、これは改善というよりは非常に不自然で望ましくない副作用だと思います。しかし、それは何年も標準になったようです。

LC_COLLATE=C を含むように /etc/locale.conf を変更すると、昔ながらの驚くべき動作が返されるはずです。

テストは渡すことができる

$ LC_COLLATE=C; ls -l

期待どおりにリストが返されます。

PS:私のDevuanシステムには/etc/locale.confが存在せず、man locale.confがそれを参照し、systemdがそれを事前に読み取ると言いますが、ファイルを生成してLC_COLLATE行を入れるだけでは不十分です。 =C入ります。おそらくここにはシステムがないからです:-)

dpkg-reconfigure ロケールで LC_COLLATE を設定することもできません。 /etc の下の既存のファイルでもこの​​設定が見つかりません。

代わりに次の行を追加しました。

export LC_COLLATE=C

~/.bashrc 入力がついに成功しました。

早くて便利な回答にもよろしくお願いします。

関連情報