가능한 최종 솔루션
그래서 나는 아래의 모든 정보를 취하여 이것을 생각해 냈습니다.
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 호환 시스템이 환경 변수 중에서 제 비어 값에 의존 LC_ALL, LC_CTYPE, LANG
하고, 명령을 통해 결정될 수있다locale charmap.
또한 주목할 가치 recode
는 그것이 API 라는 것 입니다 .
명명 된 프로그램 recode
은 단지 그 기록 라이브러리의 응용 프로그램입니다. 레코딩 라이브러리는 다른 C 프로그램에 대해 별도로 제공됩니다. 레코딩 라이브러리에 익숙해지기위한 좋은 방법은 recode
프로그램 자체에 익숙해지는 것입니다.
레코딩 라이브러리를 설치 한 후에 사용하려면 C 프로그램에 다음 줄이 있어야합니다.
#include <recode.h>
국제적으로 친숙한 문자열 비교를 위해 POSIX
및 C
표준은 strcoll()
기능을 정의합니다 .
이 strcoll()
함수는 현재 로케일의 LC_COLLATE 범주에 적절하게 해석 되는 s1
로 표시된 문자열 과로 표시된 문자열을 비교해야합니다 s2
.
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);
}
POSIX
문자 클래스 와 관련하여 이미 C
API를 사용 하여 문자 클래스 를 찾았 음을 언급했습니다 . 유니 코드 문자 및 클래스의 경우 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로 제공되지만 영어 설명은 사용할 수 없지만 프랑스어 설명은 라틴 -1을 사용하여 대신 프랑스어 설명이 제공됩니다. 그러나
LANGUAGE
or 또는 LANG
환경 변수가 문자 fr로 시작하는 경우 두 설명을 모두 사용할 수 있으면 목록 환경 설정이 프랑스어로 이동합니다.
포함 된 테스트 데이터 세트 와 결합 된 위와 유사한 구문을 사용하여 다음과 같이 내 자신의 문자 맵을 얻을 수 있습니다.
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 charmaps 여부에 관계없이 로케일 은 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
기능을 사용하여 domainname 도메인의 메시지 카탈로그에 대한 출력 문자 세트를 지정할 수 있습니다
. 코드 세트의 인수는 유효해야합니다 코드 세트 에 사용할 수있는 이름 iconv_open 함수 또는 널 포인터.
는 IF 코드 세트 매개 변수는 널 포인터, bind_textdomain_codeset
현재 선택된 반환 코드 세트 이름을 가진 도메인에 대한
도메인 이름을 . 코드 세트 가 아직 선택되지 않은 경우 NULL을 리턴합니다 .
이 bind_textdomain_codeset
기능은 여러 번 사용할 수 있습니다. 동일한 domainname 인수와 함께 여러 번 사용될 경우, 나중에 호출하면 이전 호출에 의해 작성된 설정이 무시됩니다.
이 bind_textdomain_codeset
함수는 선택한 코드 세트의 이름이 포함 된 문자열에 대한 포인터를 반환합니다. 문자열은 함수에서 내부적으로 할당되며 사용자가 변경해서는 안됩니다. 을 실행하는 동안 시스템이 코어를 벗어나
bind_textdomain_codeset
면 반환 값은 NULL이고 전역 변수 errno가 그에 따라 설정됩니다.
또한 언어에 독립적이며 POSIX 클래스를 완전히 포기하거나 후자를 정의하기에 충분한 정보를 제공하기 위해 전자를 호출 할 수있는 고유 유니 코드 문자 범주를 사용할 수도 있습니다 .
합병증 외에도 유니 코드는 새로운 가능성을 제공합니다. 하나는 각 유니 코드 문자가 특정 범주에 속한다는 것입니다 . "letter"범주에 속하는 단일 문자를와 일치시킬 수 있습니다
\p{L}
. 해당 카테고리에 속하지 않는 단일 문자를로 일치시킬 수 있습니다 \P{L}
.
"문자"는 실제로 "유니 코드 코드 포인트"를 의미합니다. \p{L}
"letter"범주의 단일 코드 포인트와 일치합니다. 입력 문자열이로 à
인코딩 된 경우 악센트없이 U+0061 U+0300
일치 a
합니다. 입력이로 à
인코딩 되면 악센트와 U+00E0
일치 à
합니다. 그 이유는 코드 포인트 U+0061 (a)
와 U+00E0 (à)
카테고리가 모두 "letter" U+0300
에 있고 카테고리는 "mark"에 있기 때문입니다.
이제 \P{M}\p{M}*+
와 같은 이유를 이해해야 \X
합니다.
\P{M}
결합 마크가 아닌 코드 포인트와 일치하는 반면, 마크를 결합하는 \p{M}*+
0 개 이상의 코드 포인트와 일치합니다. 분음 부호를 포함한 문자를 일치 시키려면을 사용하십시오 \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
에서 "ko 페이지" 예를 들어, 그리고 어느 정도는 또 다른 진짜 큰 문제는 그들이 모든 점유율을 보인다 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)
...
... 그리고 더
또한이 luit
터미널 UTF-8 pty
I는 이동 사이 xterms을위한없이 UTF-8을 지원 역할을 추측 변환 장치. 변환 된 모든 바이트를 파일 또는 -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
- 디렉토리 locales
에서 컴파일 할 수 있습니다 I18N
. 출력은 펑키하고 전혀 유용하지는 않지만 전혀 유용 charmaps
하지는 않지만 위에서 지정한 것처럼 원시 형식을 얻을 수 있습니다.
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 모듈을 호출하는 것이 나보다 조금 덜 어려울 것입니다. 다시 말하지만, 이들은 이미 내 컴퓨터에 있었고 펄도 사용하지 않습니다. 또한 I18N
내가 잘 작동하지 않으면 서두르지 않고 스크롤 한 몇 가지 가 있습니다.
/usr/share/i18n/locales/i18n
에서 가져옵니다 ... 물론 유니 코드 문자 데이터베이스에서 주로옵니다. 물론 명령을받는 것이 좋을 것입니다.