ファイル名の末尾に同じ文字を追加すると、次のようにソート順が変更されるのはなぜですか?通常の文字列比較方法では、同じ文字列が2つの文字列の末尾に追加された場合、2つの文字列の比較は変わらないと予想されます。
$ type ls
ls is aliased to `ls --color=auto`
$ touch I II III IV V VI
$ ls
I II III IV V VI
$ rm -f *
$ for n in I II III IV V VI; do touch "$n x"; done
$ ls
III x II x IV x I x VI x V x
一方、Pythonは私が期待したように動作します。
>>> ns = ['I', 'II', 'III', 'IV', 'V', 'VI']
>>> sorted(ns)
['I', 'II', 'III', 'IV', 'V', 'VI']
>>> sorted(n + ' x' for n in ns)
['I x', 'II x', 'III x', 'IV x', 'V x', 'VI x']
>>>
答え1
Cyrusのコメントからわかるように、その理由は対照規則(=ロケール認識文字列の比較)によるものです。あなたの場合、C / POSIX以外のほとんどのロケール(たとえば、「en_US.UTF-8」)の場合、文字列を比較するときにスペース文字は無視されるため、「Ix」と「Ix」は等しく評価されるため、「II」が表示されます。します。 「Ix」の前。
以下を参照してください。
$ touch I "I x" "Ix" "II" IIx "II x"
C以外のロケールを使用している場合、文字列を比較するときにスペースは通常無視されます。
$ locale | grep LANG
LANG=en_US.UTF-8
LANGUAGE=en_US
$ ls -lhog
total 0
-rw-rw-r-- 1 0 Dec 26 17:12 I
-rw-rw-r-- 1 0 Dec 26 17:12 II
-rw-rw-r-- 1 0 Dec 26 17:12 IIx
-rw-rw-r-- 1 0 Dec 26 17:12 II x
-rw-rw-r-- 1 0 Dec 26 17:12 Ix
-rw-rw-r-- 1 0 Dec 26 17:12 I x
POSIX / Cロケールを強制するために、ファイル名はASCII文字で比較されるため、「スペース」文字は「x」または「I」の前にあります。
$ LC_ALL=C ls -lhog
total 0
-rw-rw-r-- 1 0 Dec 26 17:12 I
-rw-rw-r-- 1 0 Dec 26 17:12 I x
-rw-rw-r-- 1 0 Dec 26 17:12 II
-rw-rw-r-- 1 0 Dec 26 17:12 II x
-rw-rw-r-- 1 0 Dec 26 17:12 IIx
-rw-rw-r-- 1 0 Dec 26 17:12 Ix
strcoll(3)
実際の比較関数の結果()を表示するには、ltrace
次のように使用します。
$ LC_ALL=C ltrace -e strcoll ls -lhog
ls->strcoll("I", "II x") = -73
ls->strcoll("Ix", "I") = 120
ls->strcoll("Ix", "II x") = 47
ls->strcoll("I x", "II") = -41
ls->strcoll("IIx", "I x") = 41
ls->strcoll("IIx", "II") = 120
ls->strcoll("I x", "I") = 32
ls->strcoll("I x", "II x") = -41
ls->strcoll("II", "II x") = -32
ls->strcoll("IIx", "II x") = 88
ls->strcoll("IIx", "Ix") = -47
total 0
-rw-rw-r-- 1 0 Dec 26 17:12 I
-rw-rw-r-- 1 0 Dec 26 17:12 I x
-rw-rw-r-- 1 0 Dec 26 17:12 II
-rw-rw-r-- 1 0 Dec 26 17:12 II x
-rw-rw-r-- 1 0 Dec 26 17:12 IIx
-rw-rw-r-- 1 0 Dec 26 17:12 Ix
+++ exited (status 0) +++
$ LC_ALL=en_US.UTF-8 ltrace -e strcoll ls -lhog
ls->strcoll("I", "II x") = -1
ls->strcoll("Ix", "I") = 1
ls->strcoll("Ix", "II x") = 15
ls->strcoll("I x", "II") = 15
ls->strcoll("IIx", "II") = 1
ls->strcoll("IIx", "I x") = -15
ls->strcoll("II", "I") = 1
ls->strcoll("II", "II x") = -1
ls->strcoll("IIx", "II x") = -1
ls->strcoll("I x", "II x") = 15
ls->strcoll("I x", "Ix") = 1
total 0
-rw-rw-r-- 1 0 Dec 26 17:12 I
-rw-rw-r-- 1 0 Dec 26 17:12 II
-rw-rw-r-- 1 0 Dec 26 17:12 IIx
-rw-rw-r-- 1 0 Dec 26 17:12 II x
-rw-rw-r-- 1 0 Dec 26 17:12 Ix
-rw-rw-r-- 1 0 Dec 26 17:12 I x
+++ exited (status 0) +++