일부 유니코드 문자가 포함된 "uniq" 또는 "sort -u" 줄은 어디로 갔나요?

일부 유니코드 문자가 포함된 "uniq" 또는 "sort -u" 줄은 어디로 갔나요?

아래 코드 조각에서는 무슨 일이 일어나고 있나요? 예상한 결과를 얻지 못했습니다.

나는 이것이 버그라고 생각하지만 2개의 다른 프로그램(uniq 및 sort)에서 발생하므로 이것이 뭔가 관련이 있는 것으로 의심됩니다...글쎄, 무슨 일인지는 모르겠습니다...따라서 문제가 발생합니다.

처음 3개(4개 중) 예제는 작동하지만 4번째 예제는 실패합니다!

나는 모든 캐릭터가 같은 방식으로 행동하기를 원합니다.
즉. (입력 3줄 중) 2줄을 인쇄합니다... 하지만 네 번째 경우에는 1줄만 얻습니다(합산의 경우 sort -u) uniq. 두 개의 동일한 줄이 사라집니다.

보기를 간결하게 유지하기 위해 출력 '\n'을 공백으로 변환했습니다.

나는 그것을 사용하고 있다고유한그리고유형(GNU coreutils) 7.4부터... Ubuntu 10.04.3 LTS 데스크탑에서 실행됩니다.

스크립트:

{
  locale -k LC_COLLATE
  echo
  for c1 in x 〼 ;do 
    for c2 in z 〇 ;do 
      echo -n "asis   : "; echo -e "$c1\n$c2\n$c2"          |tr '\n' ' ';echo
      echo -n "uniq   : "; echo -e "$c1\n$c2\n$c2" |uniq    |tr '\n' ' ';echo
      echo -n "sort -u: "; echo -e "$c1\n$c2\n$c2" |sort -u |tr '\n' ' ';echo
      echo
    done
    echo
  done
}

산출:

collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2081
collate-codeset="UTF-8"

asis   : x z z 
uniq   : x z 
sort -u: x z 

asis   : x 〇 〇 
uniq   : x 〇 
sort -u: 〇 x 


asis   : 〼 z z 
uniq   : 〼 z 
sort -u: 〼 z 

asis   : 〼 〇 〇 
uniq   : 〼 
sort -u: 〼 

# In the last example (of 4) where did the '〇' go? .. U+3007 IDEOGRAPHIC NUMBER ZERO
#

답변1

짧은 버전: 명령줄 유틸리티에서는 데이터 정렬이 실제로 작동하지 않습니다.

더 긴 버전: 두 문자열을 비교하는 기본 함수는 다음과 같습니다.strcoll. 설명은 별로 도움이 되지 않지만 개념적으로 이를 수행하는 방법은 두 문자열을 표준 형식으로 변환한 다음 두 표준 형식을 비교하는 것입니다. 기능strxfrm이 정식 형식이 구성됩니다.

일부 문자열의 표준 형식을 살펴보겠습니다(Debian squeeze에서 GNU libc 사용).

$ export LC_ALL=en_US.UTF-8
$ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' b a A à 〼 〇
b d010801020
a c010801020
A c010801090
à 101010102c6b
〼 101010102c6b102c6b102c6b
〇 101010102c6b102c6b102c6b

보시다시피 〼과 〼는 동일한 표준형을 갖습니다. 제 생각에는 해당 문자가 en_US.UTF-8해당 로케일의 조합 테이블에 언급되지 않았기 때문인 것 같습니다. 그러나 일본어 로케일에서는 나타납니다.

$ export LC_ALL=ja_JP.UTF-8
$ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' 〼 〇 
〼 303030
〇 3c9b

로케일 데이터(Debian squeeze의) 소스 코드는 /usr/share/i18n/locales/en_USinclude 에 있습니다. 이 파일 에는 또는 항목이 /usr/share/i18n/locales/iso14651_t1_common없으며 제가 찾을 수 있는 범위에는 포함되어 있지 않습니다.U3007U303C

나는 익숙하지 않다정렬 규칙 설정 규칙, 그러나 내가 이해한 바에 따르면 관련 표현은 다음과 같습니다.

UNDEFINED 기호는 명시적으로 지정되지 않거나 줄임표로 지정되지 않은 모든 인코딩된 문자 집합 값을 포함하는 것으로 해석됩니다. (...) 정의되지 않은 기호가 지정되지 않았고 현재 인코딩된 문자 세트에 이 섹션에 지정되지 않은 문자가 포함되어 있는 경우 유틸리티는 경고 메시지를 발행하고 해당 문자를 문자 정렬 순서의 끝에 배치해야 합니다.

Glibc는 지정되지 않은 문자를 무시하는 것 같습니다. POSIX 사양을 이해하는 데 결함이 있는지, Glibc 로케일 정의에 누락된 부분이 있는지, Glibc 로케일 컴파일러에 버그가 있는지는 알 수 없습니다.

답변2

유니코드 문자열을 "안전하게" 사용하려면 sort다음을 살펴보세요 msort.

[...] Msort는 키 필드 선택, 더 많은 비교 유형, 다른 키에서 다른 로케일의 데이터 정렬을 사용하는 기능, 비서구 숫자 시스템의 숫자를 처리하는 기능 및 기타 다양한 옵션 측면에서 부족합니다. 더 큰 유연성을 제공합니다. GNU 정렬 및 BSD 정렬. msort는 유니코드를 이해하지만 GNU 정렬 및 BSD 정렬은 이해하지 못합니다. [...]

http://www.billposer.org/Software/msort.html

관련 정보