현재 로케일의 특정 문자 클래스에 있는 문자 목록을 검색하는 명령

현재 로케일의 특정 문자 클래스에 있는 문자 목록을 검색하는 명령

현재 로케일에서 특정 문자 클래스(예: blank, ... ) alpha의 모든 문자 목록을 검색할 수 있는 방법이 있습니까?digit

예를 들어,

LC_ALL=en_GB.UTF-8 that-command blank

이상적으로 내 Debian 시스템에서는 다음과 같습니다.

      09 U+0009 HORIZONTAL TAB
      20 U+0020 SPACE
e1 9a 80 U+1680 OGHAM SPACE MARK
e1 a0 8e U+180E MONGOLIAN VOWEL SEPARATOR
e2 80 80 U+2000 EN QUAD
e2 80 81 U+2001 EM QUAD
e2 80 82 U+2002 EN SPACE
e2 80 83 U+2003 EM SPACE
e2 80 84 U+2004 THREE-PER-EM SPACE
e2 80 85 U+2005 FOUR-PER-EM SPACE
e2 80 86 U+2006 SIX-PER-EM SPACE
e2 80 88 U+2008 PUNCTUATION SPACE
e2 80 89 U+2009 THIN SPACE
e2 80 8a U+200A HAIR SPACE
e2 81 9f U+205F MEDIUM MATHEMATICAL SPACE
e3 80 80 U+3000 IDEOGRAPHIC SPACE

C 언어 환경에서는 다음과 유사한 내용이 표시될 수 있습니다.

09 U+0009 HORIZONTAL TAB
20 U+0020 SPACE

즉, 로케일의 문자는 바이트 배열(예: 첫 번째 예에서는 UTF-8, 두 번째 예에서는 단일 바이트), 동등한 유니코드 문자 코드 포인트 및 설명으로 표시됩니다.

문맥

(편집) 이제 취약점이 패치되고 공개된 지 오래되었으므로 몇 가지 배경 정보를 추가할 수 있습니다.

조사 중에 이런 질문을 했어요.CVE2014-0475. 사용자가 표준 시스템 로케일 검색 경로를 기준으로 확인되는 로케일을 glibc사용하여 모든 파일을 로케일 정의로 사용할 수 있게 하는 버그가 있습니다 .LC_ALL=../../../../tmp/evil-locale

불량 로캘을 만들 수 있습니다.s예를 들어 , h및 일부 다른 문자를 제외한 대부분의 문자가 고려되는 문자당 1바이트 문자 집합입니다.공백이는 일반적인 데비안 파일을 구문 분석할 때 실행됩니다 bash(호스팅 서버에서 셸 액세스를 얻는 데 사용할 수 있습니다. 예를 들어 서버 사용자로 로그인 셸을 제공하고 서버는 / 변수를 허용하며 공격자는 파일을 서버) .sh/etc/bash.bashrcgitbashgitsshLC_*LANG

이제 LC_CTYPE에서 하나(컴파일된 로케일 정의)를 찾으면 /tmp/evil그것이 잘못된 정의인지 어떻게 발견할 수 있으며 어떤 방식으로 이를 발견할 수 있습니까?

따라서 내 목표는 이러한 로케일 정의를 컴파일 해제하고, 그렇지 않다면 적어도 주어진 문자 클래스의 문자(및 해당 인코딩)를 아는 것입니다.

따라서 다음을 고려하십시오.

  • 내 경우에는 로케일 소스 파일( /usr/share/i18n/locale데비안의 로케일과 같은 로케일 정의)을 보는 솔루션이 작동하지 않았습니다.
  • 유니코드 문자 속성은 관련이 없습니다. 나는 로케일의 내용에만 관심이 있습니다. Debian 시스템에서는 클래스의 문자 목록이 두 개의 UTF-8 시스템 로케일(불량 시스템 로케일은 물론) 간에도 다를 수 있습니다.
  • recode, 같은 도구 python는 바이트/멀티바이트에서 문자로의 변환을 수행하며 실제로는 로케일과 다른 방식으로 변환할 수 있으므로 사용할 수 없습니다 .perl

답변1

가능한 최종 솔루션

그래서 저는 다음과 같은 정보를 모두 수집하여 다음과 같은 결론에 도달했습니다.

for class in $(
    locale -v LC_CTYPE | 
    sed 's/combin.*//;s/;/\n/g;q'
) ; do 
    printf "\n\t%s\n\n" $class
    recode u2/test16 -q </dev/null | 
    tr -dc "[:$class:]" | 
    od -A n -t a -t o1z -w12
done

노트:

od나는 다중 바이트 문자를 사용하지 않을 것이고 이를 올바르게 처리하지 못할 것이라는 것을 알았기 때문에 선호도에서 위의 최종 필터로 사용했습니다 . recode u2..dump둘 다 질문에 지정된 것과 유사한 출력을 생성하고 와이드 문자를 올바르게 처리합니다.

산출

        upper

   A   B   C   D   E   F   G   H   I   J   K   L
 101 102 103 104 105 106 107 110 111 112 113 114  >ABCDEFGHIJKL<
   M   N   O   P   Q   R   S   T   U   V   W   X
 115 116 117 120 121 122 123 124 125 126 127 130  >MNOPQRSTUVWX<
   Y   Z
 131 132                                          >YZ<

        lower

   a   b   c   d   e   f   g   h   i   j   k   l
 141 142 143 144 145 146 147 150 151 152 153 154  >abcdefghijkl<
   m   n   o   p   q   r   s   t   u   v   w   x
 155 156 157 160 161 162 163 164 165 166 167 170  >mnopqrstuvwx<
   y   z
 171 172                                          >yz<

        alpha

   A   B   C   D   E   F   G   H   I   J   K   L
 101 102 103 104 105 106 107 110 111 112 113 114  >ABCDEFGHIJKL<
   M   N   O   P   Q   R   S   T   U   V   W   X
 115 116 117 120 121 122 123 124 125 126 127 130  >MNOPQRSTUVWX<
   Y   Z   a   b   c   d   e   f   g   h   i   j
 131 132 141 142 143 144 145 146 147 150 151 152  >YZabcdefghij<
   k   l   m   n   o   p   q   r   s   t   u   v
 153 154 155 156 157 160 161 162 163 164 165 166  >klmnopqrstuv<
   w   x   y   z
 167 170 171 172                                  >wxyz<

        digit

   0   1   2   3   4   5   6   7   8   9
 060 061 062 063 064 065 066 067 070 071          >0123456789<

       xdigit                                                                                          

   0   1   2   3   4   5   6   7   8   9   A   B
 060 061 062 063 064 065 066 067 070 071 101 102  >0123456789AB<
   C   D   E   F   a   b   c   d   e   f
 103 104 105 106 141 142 143 144 145 146          >CDEFabcdef<

        space

  ht  nl  vt  ff  cr  sp
 011 012 013 014 015 040                          >..... <

        print

  sp   !   "   #   $   %   &   '   (   )   *   +
 040 041 042 043 044 045 046 047 050 051 052 053  > !"#$%&'()*+<
   ,   -   .   /   0   1   2   3   4   5   6   7
 054 055 056 057 060 061 062 063 064 065 066 067  >,-./01234567<
   8   9   :   ;   <   =   >   ?   @   A   B   C
 070 071 072 073 074 075 076 077 100 101 102 103  >89:;<=>?@ABC<
   D   E   F   G   H   I   J   K   L   M   N   O
 104 105 106 107 110 111 112 113 114 115 116 117  >DEFGHIJKLMNO<
   P   Q   R   S   T   U   V   W   X   Y   Z   [
 120 121 122 123 124 125 126 127 130 131 132 133  >PQRSTUVWXYZ[<
   \   ]   ^   _   `   a   b   c   d   e   f   g
 134 135 136 137 140 141 142 143 144 145 146 147  >\]^_`abcdefg<
   h   i   j   k   l   m   n   o   p   q   r   s
 150 151 152 153 154 155 156 157 160 161 162 163  >hijklmnopqrs<
   t   u   v   w   x   y   z   {   |   }   ~
 164 165 166 167 170 171 172 173 174 175 176      >tuvwxyz{|}~<

        graph

   !   "   #   $   %   &   '   (   )   *   +   ,
 041 042 043 044 045 046 047 050 051 052 053 054  >!"#$%&'()*+,<
   -   .   /   0   1   2   3   4   5   6   7   8
 055 056 057 060 061 062 063 064 065 066 067 070  >-./012345678<
   9   :   ;   <   =   >   ?   @   A   B   C   D
 071 072 073 074 075 076 077 100 101 102 103 104  >9:;<=>?@ABCD<
   E   F   G   H   I   J   K   L   M   N   O   P
 105 106 107 110 111 112 113 114 115 116 117 120  >EFGHIJKLMNOP<
   Q   R   S   T   U   V   W   X   Y   Z   [   \
 121 122 123 124 125 126 127 130 131 132 133 134  >QRSTUVWXYZ[\<
   ]   ^   _   `   a   b   c   d   e   f   g   h
 135 136 137 140 141 142 143 144 145 146 147 150  >]^_`abcdefgh<
   i   j   k   l   m   n   o   p   q   r   s   t
 151 152 153 154 155 156 157 160 161 162 163 164  >ijklmnopqrst<
   u   v   w   x   y   z   {   |   }   ~
 165 166 167 170 171 172 173 174 175 176          >uvwxyz{|}~<

        blank

  ht  sp
 011 040                                          >. <

        cntrl

 nul soh stx etx eot enq ack bel  bs  ht  nl  vt
 000 001 002 003 004 005 006 007 010 011 012 013  >............<
  ff  cr  so  si dle dc1 dc2 dc3 dc4 nak syn etb
 014 015 016 017 020 021 022 023 024 025 026 027  >............<
 can  em sub esc  fs  gs  rs  us del
 030 031 032 033 034 035 036 037 177              >.........<

        punct

   !   "   #   $   %   &   '   (   )   *   +   ,
 041 042 043 044 045 046 047 050 051 052 053 054  >!"#$%&'()*+,<
   -   .   /   :   ;   <   =   >   ?   @   [   \
 055 056 057 072 073 074 075 076 077 100 133 134  >-./:;<=>?@[\<
   ]   ^   _   `   {   |   }   ~
 135 136 137 140 173 174 175 176                  >]^_`{|}~<

        alnum

   0   1   2   3   4   5   6   7   8   9   A   B
 060 061 062 063 064 065 066 067 070 071 101 102  >0123456789AB<
   C   D   E   F   G   H   I   J   K   L   M   N
 103 104 105 106 107 110 111 112 113 114 115 116  >CDEFGHIJKLMN<
   O   P   Q   R   S   T   U   V   W   X   Y   Z
 117 120 121 122 123 124 125 126 127 130 131 132  >OPQRSTUVWXYZ<
   a   b   c   d   e   f   g   h   i   j   k   l
 141 142 143 144 145 146 147 150 151 152 153 154  >abcdefghijkl<
   m   n   o   p   q   r   s   t   u   v   w   x
 155 156 157 160 161 162 163 164 165 166 167 170  >mnopqrstuvwx<
   y   z

프로그래머의 API

아래에서 보여주듯이 recode완전한 캐릭터 다이어그램이 제공됩니다. 매뉴얼에 따르면 먼저 DEFAULT_CHARSET환경 변수의 현재 값을 기반으로 이 작업을 수행하고, 그렇지 않으면지정한 대로 정확하게 실행됩니다.

언제문자 집합이름을 생략하거나 공백으로 두면 DEFAULT_CHARSET환경에 있는 변수의 값이 사용됩니다. 이 변수가 정의되지 않은 경우 라이브러리는 recode다음을 사용합니다.현재 로캘의 인코딩입니다.존재하다POSIX호환 가능한 시스템은 환경 변수의 null이 아닌 첫 번째 값에 따라 달라지며 LC_ALL, LC_CTYPE, LANG, 이는 명령으로 확인할 수 있습니다.locale charmap.

또한 주목할 만한 recode점은API입니다:

이 프로그램은 recode녹음 라이브러리의 하나의 응용 프로그램일 뿐입니다. 레코딩 라이브러리는 다른 C 프로그램과 독립적으로 사용할 수 있습니다. 녹음 라이브러리에 익숙해지는 좋은 방법은 프로그램 recode자체에 익숙해지는 것입니다.

설치 후 레코딩 라이브러리를 사용하려면 C 프로그램에 다음 한 줄이 있어야 합니다.

#include <recode.h>

국제 친화적인 문자열 비교 POSIXC​​표준 정의strcoll()기능:

이 함수는 strcoll()가리키는 문자열과 가리키는 문자열을 s1비교 해야 하며 s2, 둘 다 현재 로케일의 LC_COLLATE 범주에 적절하게 해석됩니다.

성공하면 이 strcoll()함수는 errno 설정을 변경해서는 안 됩니다.

오류를 나타내는 반환 값이 유지되지 않기 때문에 오류 조건을 확인하려는 응용 프로그램은 errno를 0으로 설정하고 호출한 다음 strcoll()errno를 확인해야 합니다.

여기 하나 있어요각각 위치한사용법의 예:

#include <stdio.h>
#include <string.h>

int main ()
{
   char str1[15];
   char str2[15];
   int ret;


   strcpy(str1, "abc");
   strcpy(str2, "ABC");

   ret = strcoll(str1, str2);

   if(ret > 0)
   {
      printf("str1 is less than str2");
   }
   else if(ret < 0) 
   {
      printf("str2 is less than str1");
   }
   else 
   {
      printf("str1 is equal to str2");
   }

   return(0);
}

캐릭터 클래스에 관해서는 API를 POSIX사용하여 C찾는다는 사실을 이미 알고 계셨습니다. 유니코드 문자 및 클래스의 경우 다음을 사용할 수 있습니다.recode's 덤프 이름원하는 출력을 얻기 위한 문자 집합입니다. 그것에서수동으로 다시:

예를 들어, 이 명령은 recode l2..full < input다음에서 시작한다는 의미입니다.라틴어 2도착하다UCS-2,~처럼덤프 이름다음의 링크만UCS-2.이 경우 recode원본 내용은 표시되지 않습니다. 라틴어 2덤프의 코드는 다음에만 해당합니다.UCS-2가치. 더 간단한 예를 들자면 다음 명령을 사용하세요.

 echo 'Hello, world!' | recode us..dump

다음과 같은 출력이 생성됩니다.

UCS2   Mne   Description

0048   H     latin capital letter h 
0065   e     latin small letter e
006C   l     latin small letter l 
006C   l     latin small letter l
006F   o     latin small letter o 
002C   ,     comma 
0020  SP     space 
0077   w     latin small letter w 
006F   o     latin small letter o 
0072   r     latin small letter r 
006C   l     latin small letter l 
0064   d     latin small letter d 
0021   !     exclamation mark 
000A   LF    line feed (lf)

설명문은 영어와 ASCII로 제공되나, 영어 설명은 없고 프랑스어 설명이 있는 경우에는 Latin-1을 사용하여 프랑스어 설명을 제공한다. 그러나 환경 변수가 문자로 시작하는 LANGUAGE경우LANG정말로을 선택하면 두 설명을 모두 사용할 수 있을 때 목록 우선순위가 프랑스어로 변경됩니다.

위와 비슷한 구문을 사용하여 결합하세요.테스트 데이터 세트가 포함되어 있습니다.다음을 통해 나만의 캐릭터 맵을 얻을 수 있습니다.

recode -q u8/test8..dump </dev/null

산출

UCS2   Mne   Description

0001   SH    start of heading (soh)
0002   SX    start of text (stx)
0003   EX    end of text (etx)    
...
002B   +     plus sign
002C   ,     comma
002D   -     hyphen-minus
...
0043   C     latin capital letter c
0044   D     latin capital letter d
0045   E     latin capital letter e
...
006B   k     latin small letter k
006C   l     latin small letter l
006D   m     latin small letter m
...
007B   (!    left curly bracket
007C   !!    vertical line
007D   !)    right curly bracket
007E   '?    tilde
007F   DT    delete (del)

그러나 일반 캐릭터의 경우에는 recode분명히 필요하지 않습니다. 그러면 128바이트 문자 집합의 모든 항목에 대해 명명된 문자가 제공됩니다.

printf %b "$(printf \\%04o $(seq 128))" | 
luit -c |
od -A n -t o1z -t a -w12

산출

 001 002 003 004 005 006 007 010 011 012 013 014  >............<
 soh stx etx eot enq ack bel  bs  ht  nl  vt  ff
...
 171 172 173 174 175 176 177                      >yz{|}~.<
   y   z   {   |   }   ~ del

물론 128바이트만 표현하지만 그건 내 로케일 때문입니다.UTF-8문자표 유무에 관계없이 사용ASCII 코드문자 집합은 그 이상입니다. 그게 내가 가진 전부입니다. 필터링하지 않고 실행하면 luit롤백 od되고 동일한 지도가 다시 인쇄됩니다.\0400.

그러나 위의 접근 방식에는 두 가지 주요 문제가 있습니다. 첫 번째는 시스템의 조합 순서입니다. ASCII가 아닌 로케일의 경우 문자 세트의 비트 값은 중요하지 않습니다 seq. 이것이 해결하려는 문제의 핵심일 수 있다고 생각하기 때문입니다.

글쎄요, GNU tr's man페이지에는 클래스를 순차적으로 확장할 것이라고 명시되어 있지만 [:upper:] [:lower:]이는 많지 않습니다.

일부 과감한 솔루션을 사용하면 달성할 수 있다고 생각 sort하지만 백엔드 프로그래밍 API에는 다소 투박한 도구가 될 것입니다.

recode제대로 하겠지만 지난번에는 프로그램이 마음에 들지 않는 것 같았습니다. 어쩌면 오늘의 편집으로 인해 더 친근해 보일 수도 있고 그렇지 않을 수도 있습니다.

GNU는 또한 gettext다음을 수행할 수 있는 것으로 보이는 함수 라이브러리를 제공합니다.이 문제를 해결하다적어도 LC_MESSAGES맥락상:

- 기능: char * bind_textdomain_codeset( const char *domainname, const char *codeset)

bind_textdomain_codeset함수는 도메인 메시지 카탈로그의 출력 문자 집합을 지정하는 데 사용할 수 있습니다. 도메인 이름. 이것코드 세트매개변수는 유효해야 합니다.코드 세트사용 가능한 이름iconv_open함수 또는 널 포인터.

만약에코드 세트매개변수는 널 포인터이며 bind_textdomain_codeset 현재 선택된 값을 반환합니다.코드 세트이름이 있는 도메인의 경우 도메인 이름. 그렇지 않은 경우 NULL을 반환코드 세트아직 선택되지 않았습니다.

bind_textdomain_codeset기능은 여러 번 사용할 수 있습니다. 동일한 도메인 이름 매개변수가 여러 번 사용되는 경우 후속 호출은 이전 호출의 설정을 덮어씁니다.

bind_textdomain_codeset함수는 선택한 코드 세트의 이름이 포함된 문자열에 대한 포인터를 반환합니다. 이 문자열은 함수 내부에 할당되며 사용자가 변경할 수 없습니다. 시스템이 실행 중에 코어를 종료하면 bind_textdomain_codeset반환 값은 NULL이고 전역 변수 errno가 그에 따라 설정됩니다.

이 기계를 사용할 수도 있습니다.유니코드 문자범주, 이들은 언어 독립적이며 POSIX 클래스를 완전히 포기하거나 전자가 후자를 정의하는 데 충분한 정보를 제공하도록 요구할 수 있습니다.

복잡성 외에도 유니코드는 새로운 가능성도 제공합니다. 하나는 각 유니코드 문자가 특정 문자에 속한다는 것입니다.범주."문자" 카테고리에 속하는 개별 문자를 일치시킬 수 있습니다 \p{L}. 해당 카테고리에 속하지 않는 개별 문자를 일치시킬 수 있습니다 \P{L}.

다시 말하지만, "문자"는 실제로 "유니코드 코드 포인트"를 의미합니다. \p{L}"문자" 범주의 단일 코드 포인트와 일치합니다. 입력 문자열이 à 로 인코딩 된 경우 악센트 없이 U+0061 U+0300일치합니다 . a입력 à이 로 인코딩 되면 U+00E0악센트와 일치합니다. à그 이유는 코드 포인트 U+0061 (a)와 가 U+00E0 (à)모두 "문자" 범주에 속하고 U+0300"태그"는 "표시" 범주에 속하기 때문입니다.

이제 태그를 결합하는 0개 이상의 코드 포인트와 일치하는 동안 태그를 결합하지 않는 .matches 코드 포인트 \P{M}\p{M}*+와 동등한 이유를 이해해야 합니다 . 발음 구별 부호가 포함된 문자를 일치시키려면 를 사용하십시오 . 마지막 정규식은 인코딩 방법에 관계없이 항상 일치합니다. 소유 수량자는 역추적으로 인해 후속 결합 토큰 없이 비토큰과 일치하는 결과가 발생하지 않도록 보장합니다.\X\P{M}\p{M}*+\p{L}\p{M}*+à\P{M}\p{M}*+\X

위의 정보를 제공하는 동일한 웹사이트에서도 이에 대해 논의합니다.Tcl내 자신의POSIX- 규정 준수정규식을 사용하여 이를 구현하는 것이 목표를 달성하는 또 다른 방법일 수 있습니다.

마지막으로 솔루션에서는 LC_COLLATE파일 자체에 요청하여 완전한 정보를 얻을 수 있는 방법을 제안합니다.~을 위한시스템 문자 맵. 쉽지 않은 것 같지만 다음과 같이 컴파일한 후 어느 정도 성공했습니다 localedef.

<LC_COLLATE od -j2K -a -w2048 -v  | 
tail -n2 | 
cut -d' ' -f$(seq -s',' 4 2 2048) | 
sed 's/nul\|\\0//g;s/  */ /g;:s;
    s/\([^ ]\{1,3\}\) \1/\1/;ts;
    s/\(\([^ ][^ ]*  *\)\{16\}\)/\1\n/g'

 dc1 dc2 dc3 dc4 nak syn etb can c fs c rs c sp ! "
# $ % & ' ( ) * + , - . / 0 1 2
3 4 5 6 7 8 9 : ; < = > ? @ A B
C D E F G H I J K L M N O P Q R
S T U V W X Y Z [ \ ] ^ _ ` a b
c d e f g h i j k l m n o p q r
s t u v w x y z { | } ~ del soh stx etx
eot enq ack bel c ht c vt cr c si dle dc1 del

물론 현재는 결함이 있지만 적어도 가능성을 보여주기를 바랍니다.

첫눈에

strings $_/en_GB

#OUTPUT

int_select "<U0030><U0030>"
...
END LC_TELEPHONE

실제로는 별 것 아닌 것 같았지만 copy목록 전체에서 명령이 눈에 띄기 시작했습니다. 위의 파일은 copy다음 위치에 있는 것 같습니다."en_US"예를 들어, 그들 모두가 어느 정도 공유하고 있는 또 다른 큰 문제는 입니다 iso_14651_t1_common.

그것은 꽤 크다:

strings $_ | wc -c

#OUTPUT
431545

소개는 다음과 같습니다 /usr/share/i18n/locales/POSIX.

# Territory:
# Revision: 1.1
# Date: 1997-03-15
# Application: general
# Users: general
# Repertoiremap: POSIX
# Charset: ISO646:1993
# Distribution and use is free, also for
# commercial purposes.
LC_CTYPE
# The following is the POSIX Locale LC_CTYPE.
# "alpha" is by default "upper" and "lower"
# "alnum" is by definiton "alpha" and "digit"
# "print" is by default "alnum", "punct" and the <U0020> character
# "graph" is by default "alnum" and "punct"
upper   <U0041>;<U0042>;<U0043>;<U0044>;<U0045>;<U0046>;<U0047>;<U0048>;\
        <U0049>;<U004A>;<U004B>;<U004C>;<U004D>;<U004E>;<U004F>;

...

grep확실히 통과할 수 있지만 다음과 같이 할 수도 있습니다 .

recode -lf gb

대신에. 당신은 다음과 같은 것을 얻을 것입니다 :

Dec  Oct Hex   UCS2  Mne  BS_4730

  0  000  00   0000  NU   null (nul)
  1  001  01   0001  SH   start of heading (soh)
...

...그리고 더

UTF-8을 지원하지 않는 XTerms의 중개인인 luit터미널 UTF-8 번역 기능 도 있습니다 . pty변환된 모든 바이트를 파일에 기록하거나 -c간단한 |pipe필터로 작동하는 등 많은 스위치를 처리합니다.

나는 로케일과 문자 매핑 등 그 안에 그렇게 많은 것이 있다는 것을 결코 깨닫지 못했습니다. 이것은 분명히 매우큰 거래하지만 내 생각엔 이 모든 일이 무대 뒤에서 일어나고 있는 것 같아요. 적어도 내 시스템에는 man 3로케일 관련 검색에 대한 관련 결과가 수백 개 있습니다.

그리고 또한:

zcat /usr/share/i18n/charmaps/UTF-8*gz | less

    CHARMAP
<U0000>     /x00         NULL
<U0001>     /x01         START OF HEADING
<U0002>     /x02         START OF TEXT
<U0003>     /x03         END OF TEXT
<U0004>     /x04         END OF TRANSMISSION
<U0005>     /x05         ENQUIRY
...

이건 한동안 지속될 거야매우잠시 동안.

이러한 Xlib함수는 이를 항상 처리하며 luit패키지의 일부입니다.

이러한 Tcl_uni...기능은 유용할 수도 있습니다.

약간의 <tab>작업과 man검색을 통해 이 주제에 대해 많은 것을 배웠습니다.

사용 - 디렉토리에서 컴파일할 수 있습니다 localedef. 출력은 이상하고 특별히 유용하지 않습니다. 전혀 유용하지 않습니다. 하지만 위에서 지정한 대로 원본 형식을 얻을 수 있습니다.localesI18Ncharmaps

mkdir -p dir && cd $_ ; localedef -f UTF-8 -i en_GB ./ 

ls -l
total 1508
drwxr-xr-x 1 mikeserv mikeserv      30 May  6 18:35 LC_MESSAGES
-rw-r--r-- 1 mikeserv mikeserv     146 May  6 18:35 LC_ADDRESS
-rw-r--r-- 1 mikeserv mikeserv 1243766 May  6 18:35 LC_COLLATE
-rw-r--r-- 1 mikeserv mikeserv  256420 May  6 18:35 LC_CTYPE
-rw-r--r-- 1 mikeserv mikeserv     376 May  6 18:35 LC_IDENTIFICATION
-rw-r--r-- 1 mikeserv mikeserv      23 May  6 18:35 LC_MEASUREMENT
-rw-r--r-- 1 mikeserv mikeserv     290 May  6 18:35 LC_MONETARY
-rw-r--r-- 1 mikeserv mikeserv      77 May  6 18:35 LC_NAME
-rw-r--r-- 1 mikeserv mikeserv      54 May  6 18:35 LC_NUMERIC
-rw-r--r-- 1 mikeserv mikeserv      34 May  6 18:35 LC_PAPER
-rw-r--r-- 1 mikeserv mikeserv      56 May  6 18:35 LC_TELEPHONE
-rw-r--r-- 1 mikeserv mikeserv    2470 May  6 18:35 LC_TIME

그런 다음 od바이트와 문자열을 읽을 수 있습니다.

od -An -a -t u1z -w12 LC_COLLATE | less

 etb dle enq  sp dc3 nul nul nul   T nul nul nul
  23  16   5  32  19   0   0   0  84   0   0   0  >... ....T...<
...

미인대회에서 우승하려면 아직 갈 길이 멀지만, 가능한 결과는 이 정도다. 물론 od필요에 맞게 구성할 수도 있습니다.

내 생각엔 이것도 잊어버린 것 같아:

    perl -mLocale                                                                                       

 -- Perl module --
Locale::Codes                    Locale::Codes::LangFam           Locale::Codes::Script_Retired
Locale::Codes::Constants         Locale::Codes::LangFam_Codes     Locale::Country
Locale::Codes::Country           Locale::Codes::LangFam_Retired   Locale::Currency
Locale::Codes::Country_Codes     Locale::Codes::LangVar           Locale::Language
Locale::Codes::Country_Retired   Locale::Codes::LangVar_Codes     Locale::Maketext
Locale::Codes::Currency          Locale::Codes::LangVar_Retired   Locale::Maketext::Guts
Locale::Codes::Currency_Codes    Locale::Codes::Language          Locale::Maketext::GutsLoader
Locale::Codes::Currency_Retired  Locale::Codes::Language_Codes    Locale::Maketext::Simple
Locale::Codes::LangExt           Locale::Codes::Language_Retired  Locale::Script
Locale::Codes::LangExt_Codes     Locale::Codes::Script            Locale::gettext
Locale::Codes::LangExt_Retired   Locale::Codes::Script_Codes      locale

아마 내가 그 사람들을 일하게 할 수 없었기 때문에 그 일들을 잊어버렸던 것 같아요. 나는 그것을 사용해본 적이 없고 Perl모듈을 올바르게 로드하는 방법을 모르는 것 같습니다. 하지만 man페이지는 꽤 좋아 보입니다. 어쨌든, 내가 했던 것보다 적어도 약간 더 쉽게 Perl 모듈을 호출할 수 있다는 것을 알게 될 것입니다. 게다가 이것들은 이미 내 컴퓨터에 있습니다. 그리고 저는 Perl을 사용해 본 적도 없습니다. 주목할만한 또 다른 점 I18N은 나도 스크롤을 할 수 없다는 것을 잘 알고 있기 때문에 스크롤하고 싶어한다는 것입니다.

답변2

적어도 GNU, FreeBSD 또는 Solaris 시스템에서는 이 무차별 대입 방법이 작동합니다.

#include <wctype.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  unsigned long i;
  int need_init;
  wctype_t type;
  FILE* to_perl;

  setlocale(LC_ALL,"");
  if (argc != 2) {
    fprintf(stderr, "Usage: %s <type>\n", (argc?argv[0] : "???"));
    exit(1);
  }
  if (!(type = wctype(argv[1]))) {
    fprintf(stderr, "Invalid type: \"%s\"\n", argv[1]);
    exit(1);
  }

  need_init = wctomb(0, 0);

  to_perl = popen("perl -Mcharnames=full -ane '"
                  "printf \"%17s U+%04X %s\n\", join(\" \", @F[1..$#F]),"
                  "$F[0], charnames::viacode($F[0])'", "w");

#ifdef SUPPORT_ROGUE_LOCALES
  for(i=0; i<=0x7fffffff; i++) {
#else
  for(i=0; i<=0x10ffff; i++) {
    if (i == 0xd800) i = 0xe000; /* skip UTF-16 surrogates */
#endif
    if (iswctype(i, type)) {
      int n;
      unsigned char buf[1024];

      if (need_init) wctomb(0, 0);
      n = wctomb(buf, i);

      if (n > 0) {
        int c;
        fprintf(to_perl, "%lu", i);
        for (c = 0; c < n; c++)
          fprintf(to_perl, " %02X", buf[c]);
        putc('\n', to_perl);
      }
    }
  }
  pclose(to_perl);
  return 0;
}

C/POSIX에 따르면 wchar_t이는 유니코드와 아무 관련이 없고 시스템 로케일에서 지원하는 모든 문자만 포함하는 불투명 유형이지만 실제로 대부분의 유니코드 인식 시스템에서 이러한 값은 유니코드에 해당합니다. 코드 포인트 및 로케일 정의 자체는 유니코드를 기반으로 합니다.

유니코드는 알려진 모든 문자 집합의 상위 집합이므로 순환 유니코드(0~0xD7FF 및 0xE000~0x10FFFF)의 모든 유효한 코드 포인트는 최소한 지정된 문자 집합에서 지원하는 모든 문자를 나열해야 합니다.

여기서는 시스템의 로케일 표준 API를 사용하여 어떤 유형이 특정 유형에 속하는지 확인하고 이를 로케일 인코딩의 인코딩으로 변환합니다. 우리는 주어진 유니코드 코드 포인트에서 이름을 얻기 위해 perl해당 모듈을 사용합니다.charnames

상태 저장 인코딩(예: ISO-2022-JP)을 사용하는 로케일에서는 인코딩 형식이 기본 초기 상태에서 표시되는지 확인합니다.

상태 저장 문자 인코딩이 설치된 로케일이 있는 시스템을 찾지 못했지만 적어도 GNU 시스템에서는 악성 로케일이 만들어질 수 있도록 일부 로케일을 생성하는 것이 가능합니다(적어도 GNU 도구는 시스템에서 제대로 작동하지 않습니다). 이러한 시스템) 로캘). 예를 들어 ISO-2022-JP 및 일반 로케일을 사용하는 ja_JP사용자 정의 로케일 의 경우 다음을 얻습니다.

$ LOCPATH=$PWD LC_ALL=ja_JP.ISO-2022-JP ~/list-type blank
       09 U+0009 CHARACTER TABULATION
       20 U+0020 SPACE
   1B 24 42 21 21 U+3000 IDEOGRAPHIC SPACE

비교:

$ LC_ALL=ja_JP.eucjp ~/list-type blank
       09 U+0009 CHARACTER TABULATION
       20 U+0020 SPACE
    A1 A1 U+3000 IDEOGRAPHIC SPACE

ISO-2022-JP에서 1B 24 42시퀀스( \e$B)는 ASCII에서 문자가 2(7비트) 바이트로 표시되는 상태로 전환됩니다(여기서 21 21은 이 표의 문자 공간을 나타냄). EUCJP에서는 바이트가 동일하지만상태 전환이는 비트 8( )을 뒤집어서 수행되며 A1 = 21 | 0x80, 이는 상태를 유지하지 않게 만듭니다.

이는 이러한 상태 저장 인코딩에는 특정 문자를 작성하는 여러 가지 방법이 있음을 의미합니다(예: 여러 문자 삽입).상태 전환시퀀스), 위 코드에 표시된 시퀀스는 그 중 하나일 뿐입니다(초기 기본 상태에 대한 표준 시퀀스).

일반 언어 환경의 경우 문자는 0..0xD7FF, 0xE000..0x10FFFF 범위를 초과할 수 없습니다.도적로케일에서는 wchar_t가 지원하는 범위 내의 모든 문자가 가능합니다. 예를 들어 U+DCBA 또는 U+12345678 문자(또는 허용되는 경우 해당 문자)로 로캘을 만들 수 있습니다.공백. -D SUPPORT_ROGUE_LOCALES이것이 전체 목록을 스캔하는 데 더 많은 시간이 걸린다는 것을 의미하더라도 이를 처리하기 위해 코드를 컴파일하려는 이유입니다 .

recode@mikeserv의 솔루션 은 자체 변환을 사용하고 더 이상 유지 관리되지 않으며 최대 0xFFFF의 유니코드 문자만 지원하고 GNU는 tr적어도 멀티바이트 문자를 지원하지 않기 때문에 사용할 수 없습니다 .

사용할 수 없습니다@christang의POSIX 문자 클래스에 대한 인터페이스 가 python없습니다.

Perl을 사용해 보았지만 UTF-8 이외의 멀티바이트 로케일에서는 128에서 255 사이의 코드 포인트에 대해 동일하게 적용되며 시스템의 변환 라이브러리를 사용하지 않습니다.

관련 정보