ls 기본 정렬이 일관성이 없습니다.

ls 기본 정렬이 일관성이 없습니다.

파일 이름 끝에 동일한 문자를 추가하면 아래와 같이 정렬 순서가 변경되는 이유는 무엇입니까? 정상적인 문자열 비교 방법에서는 동일한 문자열이 두 문자열의 끝에 추가되면 두 문자열의 비교가 다르지 않을 것으로 예상됩니다.

$ 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) +++

관련 정보