파일 이름을 정렬할 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
나는 Debian의 기본 정렬 옵션과 정확히 동일한 문제를 겪고 있습니다. 나에게는 쉼표가 무시되어 CSV 데이터를 효과적으로 정렬하지 못하게 하여 AI에 혼란을 야기합니다.
해결책은 sort
자체적으로 사용하는 대신 -d, --dictionary-order
.
명령 실행:
sort -V
내 문제를 해결하고 쉼표를 고려합니다.
답변4
그냥 코멘트입니다... 내 데이터 정렬(es_AR.utf8)에 큰 문제가 있습니다. 왜냐하면 악센트가 있기 때문에 'C'를 사용할 수 없기 때문입니다. 그리고 가장 나쁜 것은 문제가 db postgresql에도 나타나서 '10 사이의 문장을 수행한다는 것입니다. ' 및 '10.1'에는 예상하지 못한 '100' 값이 포함됩니다(예시임).. 각 쿼리에서 데이터 정렬을 사용해야 하는 것 같습니다.. '10' AND '10.Z 사이에서 '100'을 선택합니다. '는 true로 표시되지만 '10'과 '10.Z' 사이에서 '100'을 선택하세요. COLLATE "C"는 'false'를 표시하는데 이는 올바른 것입니다(내 생각에는).