ls 정렬이 영숫자가 아닌 문자를 무시하는 이유는 무엇입니까?

ls 정렬이 영숫자가 아닌 문자를 무시하는 이유는 무엇입니까?

파일 이름 정렬 시 ls무시합니다 -,_. 정렬 시에도 이 문자를 사용하고 싶습니다.

한 가지 예:

touch a1 a2 a-1 a-2 a_1 a_2 a.1 a.2 a,1 a,2

이제 다음 파일을 표시하십시오 ls -1.

a1
a_1
a-1
a,1
a.1
a2
a_2
a-2
a,2
a.2

내가 기대하는 것은 이것이다:

a1
a2
a,1
a,2
a.1
a.2
a_1
a_2
a-1
a-2

즉, 정렬할 때 영숫자가 아닌 문자를 고려하고 싶습니다.

누구든지 이 동작을 설명할 수 있나요? 이 동작은 표준에 의해 시행됩니까? 아니면 인코딩이 UTF-8이기 때문인가요?

고쳐 쓰다:이는 UTF-8 정렬과 관련이 있는 것 같습니다.

$ LC_COLLATE=C ls -1
a,1
a,2
a-1
a-2
a.1
a.2
a1
a2
a_1
a_2

답변1

편집: LC_COLLATE=C로 정렬된 데이터에 대한 테스트를 추가했습니다.


기본 조합 순서는 해당 "구두점 유형" 문자를 동일한 값을 갖는 것으로 처리합니다. Use LC_COLLATE=C코드 포인트 순서로 처리합니다.

for i in 'a1' 'a_1' 'a-1' 'a,1' 'a.1' 'a2' 'a_2' 'a-2' 'a,2' 'a.2' ;do
  echo $i; 
done |LC_COLLATE=C sort

산출

a,1
a,2
a-1
a-2
a.1
a.2
a1
a2
a_1
a_2

다음 코드는 모두 테스트합니다.효과적인기본 다국어 평면의 UTF-8 문자(예외\x00그리고\x0a; 단순화를 위해)
알려진(생성된) 오름차순 순서의 파일을 무작위로 정렬된 파일과 비교한 다음 LC_COLLATE=C를 사용하여 다시 정렬합니다. 결과는,시퀀스는 원래 생성된 시퀀스와 동일합니다.

{ i=0 j=0 k=0 l=0
  for i in {0..9} {A..F} ;do
  for j in {0..9} {A..F} ;do
  for k in {0..9} {A..F} ;do
  for l in {0..9} {A..F} ;do
     (( 16#$i$j$k$l == 16#0000 )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l == 16#000A )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l >= 16#D800    && 
        16#$i$j$k$l <= 16#DFFF )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l >= 16#FFFE )) && { printf '.' >&2; continue; }
     echo 0x"$i$j$k$l" |recode UTF-16BE/x4..UTF-8 || { echo "ERROR at codepoint $i$j$k$l " >&2; continue; } 
     echo 
  done
  done
  done; echo -n "$i$j$k$l " >&2
  done; echo >&2
} >listGen

             sort -R listGen    > listRandom
LC_COLLATE=C sort    listRandom > listCsort 

diff <(cat listGen;   echo "last line of listOrig " ) \
     <(cat listCsort; echo "last line of listCsort" )
echo 
cmp listGen listCsort; echo 'cmp $?='$?

산출:

63485c63485
< last line of listOrig 
---
> last line of listCsort

cmp $?=0

답변2

이는 문자셋과 관련이 없습니다. 대신, 순서 규칙을 결정하는 것은 언어입니다. libc는 $LC_COLLATE// $LC_ALL에 표시된 언어를 확인 $LANG하고 해당 조합(예: GLibC)을 찾은 다음 /usr/share/i18n/locales/*지시된 대로 텍스트를 정렬합니다.

답변3

나는 데비안의 기본 정렬 옵션과 똑같은 문제를 겪었고, 나에게는 쉼표를 무시하여 CSV 데이터를 효율적으로 정렬하지 못하게 하여 AI에 큰 피해를 입혔습니다.

해결책은 sort정렬을 단독으로 사용하는 대신 정렬이 기본 동작으로 나타나도록 강제해야 한다는 것입니다 -d, --dictionary-order.

실행 명령:

sort -V

내 문제를 해결하고 쉼표를 고려하십시오.

답변4

그냥 코멘트입니다... 액센트 때문에 'C'를 사용할 수 없기 때문에 내 데이터 정렬(es_AR.utf8)에 큰 문제가 있습니다. 그리고 가장 나쁜 것은 문제가 데이터베이스 postgresql에도 존재한다는 것입니다. 10 '10'과 '10.1' 사이의 문장에 포함(예시임) '100' 값을 기대하지 않습니다.. 모든 쿼리에서 대조를 사용해야 하는 것 같습니다.. '10'과 '10 사이 .Z SELECT '100' '은 true를 표시하지만 SELECT '100' BETWEEN '10' AND '10.Z' COLLATE "C"는 올바른 'false'를 표시합니다(제 생각에는).

관련 정보