파일 이름을 정렬 할 때 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
답변
이것은 문자셋과 관련이 없습니다. 데이터 정렬 순서를 결정하는 언어입니다. libc는 $LC_COLLATE
/ $LC_ALL
/ 로 표시된 언어를 검사 $LANG
하고 데이터 정렬 규칙 (예 : /usr/share/i18n/locales/*
GLibC)을 조회하고 지시에 따라 텍스트를 정렬 합니다.
답변
편집 : 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. 결과는 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