GIẢI PHÁP CUỐI CÙNG
Vì vậy, tôi đã lấy tất cả các thông tin dưới đây và đưa ra điều này:
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
LƯU Ý :
Tôi sử dụng od
làm bộ lọc cuối cùng ở trên để ưu tiên và vì tôi biết tôi sẽ không làm việc với các ký tự nhiều byte, nên nó sẽ không xử lý chính xác. recode u2..dump
cả hai sẽ tạo đầu ra giống như được chỉ định trong câu hỏi và xử lý chính xác các ký tự rộng.
ĐẦU RA
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 chương trình
Như tôi trình bày dưới đây, recode
sẽ cung cấp cho bạn bản đồ nhân vật hoàn chỉnh của bạn. Theo hướng dẫn của nó, nó thực hiện điều này trước tiên theo giá trị hiện tại của DEFAULT_CHARSET
biến môi trường hoặc, nếu không, nó hoạt động chính xác như bạn chỉ định:
Khi một tên bộ ký tự bị bỏ qua hoặc để trống, giá trị của DEFAULT_CHARSET
biến trong môi trường được sử dụng thay thế. Nếu biến này không được xác định, recode
thư viện sẽ sử dụng mã hóa của miền địa phương hiện tại. Trên các hệ thống tuân thủ POSIX , điều này phụ thuộc vào giá trị không trống đầu tiên trong số các biến môi trường LC_ALL, LC_CTYPE, LANG
và có thể được xác định thông qua lệnhlocale charmap.
Cũng đáng chú ý recode
là nó là một api :
Chương trình có tên recode
chỉ là một ứng dụng của thư viện mã hóa. Thư viện mã hóa có sẵn riêng cho các chương trình C khác. Một cách tốt để có được sự quen thuộc với thư viện mã hóa là làm quen với recode
chính chương trình.
Để sử dụng thư viện mã hóa sau khi được cài đặt, chương trình C cần phải có một dòng:
#include <recode.h>
Để so sánh chuỗi thân thiện với quốc tế Các tiêu chuẩn POSIX
và C
định nghĩa strcoll()
hàm:
Các strcoll()
chức năng có trách nhiệm so sánh chuỗi trỏ đến bởi s1
vào chuỗi trỏ đến bởi s2
, cả hai hiểu là phù hợp với loại LC_COLLATE của miền địa phương hiện nay.
Các strcoll()
chức năng sẽ không thay đổi các thiết lập của errno nếu thành công.
Vì không có giá trị trả về được dành riêng để chỉ ra lỗi, nên một ứng dụng muốn kiểm tra các tình huống lỗi sẽ đặt errno thành 0, sau đó gọi
strcoll()
, sau đó kiểm tra errno.
Đây là một ví dụ riêng về việc sử dụng nó:
#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);
}
Về các POSIX
lớp ký tự, bạn đã lưu ý rằng bạn đã sử dụng C
API để tìm các lớp này. Đối với các ký tự và lớp unicode, bạn có thể sử dụng recode's
bộ ký tự kết xuất có tên để có đầu ra mong muốn. Từ hướng dẫn của nó một lần nữa :
Ví dụ, lệnh recode l2..full < input
ngụ ý một chuyển đổi cần thiết từ Latin-2 sang UCS-2, vì dump-with-name chỉ được kết nối từ UCS-2. Trong các trường hợp như vậy, recode
không hiển thị mã Latin-2 gốc
trong kết xuất, chỉ có các giá trị UCS-2 tương ứng . Để đưa ra một ví dụ đơn giản hơn, lệnh
echo 'Hello, world!' | recode us..dump
tạo ra đầu ra sau:
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)
Nhận xét mô tả được đưa ra bằng tiếng Anh và ASCII, tuy nhiên nếu mô tả bằng tiếng Anh không có nhưng tiếng Pháp là, thì mô tả tiếng Pháp được đưa ra thay vào đó, sử dụng tiếng Latin-1. Tuy nhiên, nếu biến
LANGUAGE
hoặc LANG
môi trường bắt đầu bằng các chữ cái fr , thì ưu tiên liệt kê sẽ chuyển sang tiếng Pháp khi cả hai mô tả đều có sẵn.
Sử dụng cú pháp tương tự như trên kết hợp với tập dữ liệu thử nghiệm đi kèm, tôi có thể lấy bản đồ ký tự của riêng mình với:
recode -q u8/test8..dump </dev/null
ĐẦU RA
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)
Nhưng đối với các nhân vật thông thường, recode
rõ ràng là không cần thiết. Điều này sẽ cung cấp cho bạn các ký tự được đặt tên cho mọi thứ trong bộ ký tự 128 byte:
printf %b "$(printf \\%04o $(seq 128))" |
luit -c |
od -A n -t o1z -t a -w12
ĐẦU RA
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
Tất nhiên, chỉ có 128 byte được biểu diễn, nhưng đó là vì ngôn ngữ địa phương của tôi, không có bùa chú hay không, sử dụng bảng mã ASCII và không có gì nữa. Vì vậy, đó là tất cả những gì tôi nhận được. Nếu tôi chạy nó mà không luit
lọc nó, mặc dù vậy, od
nó sẽ cuộn lại và in lại cùng một bản đồ\0400.
Có hai vấn đề lớn với phương pháp trên, mặc dù. Đầu tiên là thứ tự đối chiếu của hệ thống - đối với các địa phương không phải ASCII, các giá trị khớp cho bộ ký tự không chỉ đơn giản là trong seq
uence, mà theo tôi nghĩ, có khả năng là cốt lõi của vấn đề bạn đang cố gắng giải quyết.
Chà, tr's man
trang GNU tuyên bố rằng nó sẽ mở rộng các [:upper:]
[:lower:]
lớp theo thứ tự - nhưng đó không phải là nhiều.
Tôi tưởng tượng một số giải pháp nặng tay có thể được thực hiện với sort
nhưng đó sẽ là một công cụ khá khó sử dụng cho API lập trình phụ trợ.
recode
sẽ làm điều này một cách chính xác, nhưng bạn dường như không quá yêu thích chương trình này vào ngày khác. Có thể các chỉnh sửa ngày nay sẽ đưa ra ánh sáng thân thiện hơn với nó hoặc có thể không.
GNU cũng cung cấp gettext
thư viện hàm và dường như có thể giải quyết vấn đề này ít nhất là cho LC_MESSAGES
bối cảnh:
- Chức năng: char * bind_textdomain_codeset
( const char *domainname,
const char *codeset
)
Các bind_textdomain_codeset
chức năng có thể được sử dụng để xác định các bộ ký tự đầu ra cho catalog nhắn cho miền
domainname . Các codeset luận phải là một giá trị codeset tên mà có thể được sử dụng cho các iconv_open chức năng, hoặc một con trỏ null.
Nếu codeset tham số là con trỏ null, bind_textdomain_codeset
trả về đang được chọn codeset cho tên miền có tên
domainname . Nó trả về NULL nếu không codeset vẫn chưa được chọn.
Các bind_textdomain_codeset
chức năng có thể được sử dụng nhiều lần. Nếu được sử dụng nhiều lần với cùng một đối số tên miền, cuộc gọi sau sẽ ghi đè cài đặt được thực hiện bởi cuộc gọi trước đó.
Các bind_textdomain_codeset
chức năng trả về một con trỏ đến một chuỗi chứa tên của codeset chọn. Chuỗi được phân bổ nội bộ trong chức năng và người dùng không được thay đổi. Nếu hệ thống đi ra khỏi lõi trong quá trình thực thi
bind_textdomain_codeset
, giá trị trả về là NULL và biến toàn cục errno được đặt tương ứng.
Bạn cũng có thể sử dụng các loại ký tự Unicode gốc , độc lập với ngôn ngữ và từ bỏ các lớp POSIX hoàn toàn hoặc có thể gọi cho loại trước để cung cấp cho bạn đủ thông tin để xác định loại sau.
Ngoài các biến chứng, Unicode cũng mang đến những khả năng mới. Một là mỗi ký tự Unicode thuộc về một loại nhất định . Bạn có thể ghép một ký tự thuộc danh mục "chữ cái"
\p{L}
. Bạn có thể ghép một ký tự không thuộc danh mục đó với \P{L}
.
Một lần nữa, "ký tự" thực sự có nghĩa là "điểm mã Unicode". \p{L}
khớp với một điểm mã duy nhất trong danh mục "chữ cái". Nếu chuỗi đầu vào của bạn được à
mã hóa dưới dạng U+0061 U+0300
, nó khớp với a
mà không có dấu. Nếu đầu vào được à
mã hóa dưới dạng U+00E0
, nó khớp à
với dấu. Lý do là cả hai điểm mã U+0061 (a)
và U+00E0 (à)
nằm trong danh mục "chữ cái", trong khi đó U+0300
là trong danh mục "đánh dấu".
Bây giờ bạn nên hiểu tại sao \P{M}\p{M}*+
là tương đương với \X
.
\P{M}
khớp với một điểm mã không phải là dấu kết hợp, trong khi \p{M}*+
khớp với 0 hoặc nhiều điểm mã đang kết hợp dấu. Để phù hợp với một chữ cái bao gồm bất kỳ dấu phụ, sử dụng \p{L}\p{M}*+
. Regex cuối cùng này sẽ luôn khớp à
, bất kể nó được mã hóa như thế nào. Bộ định lượng sở hữu đảm bảo rằng quay lui không gây ra trùng \P{M}\p{M}*+
khớp với dấu không có dấu mà không có dấu kết hợp theo sau, điều \X
này sẽ không bao giờ làm được.
Trang web tương tự cung cấp thông tin trên cũng thảo luận về việc triển khai biểu thức Tcl
chính quy POSIX -compliant của chính họ có thể là một cách khác để đạt được mục tiêu của bạn.
Và cuối cùng trong số các giải pháp tôi sẽ đề nghị bạn có thể tự hỏi LC_COLLATE
tệp cho bản đồ ký tự hệ thống hoàn chỉnh và theo thứ tự. Điều này có vẻ không dễ thực hiện, nhưng tôi đã đạt được một số thành công với những điều sau đây sau khi biên dịch nó localedef
như được trình bày dưới đây:
<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
Đó là, thừa nhận, hiện đang thiếu sót nhưng tôi hy vọng nó chứng minh khả năng ít nhất.
TỪ CÁI NHÌN ĐẦU TIÊN
strings $_/en_GB
#OUTPUT
int_select "<U0030><U0030>"
...
END LC_TELEPHONE
Nó thực sự không giống lắm nhưng sau đó tôi bắt đầu nhận thấy copy
các lệnh trong danh sách. Ví dụ, tệp ở trên dường như copy
trong "en_US" , và một tệp lớn thực sự khác mà dường như tất cả chúng đều chia sẻ ở một mức độ nào đó iso_14651_t1_common
.
Nó khá lớn:
strings $_ | wc -c
#OUTPUT
431545
Đây là phần giới thiệu /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>;
...
Bạn có thể grep
thông qua điều này tất nhiên, nhưng bạn có thể chỉ:
recode -lf gb
Thay thế. Bạn sẽ nhận được một cái gì đó như thế này:
Dec Oct Hex UCS2 Mne BS_4730
0 000 00 0000 NU null (nul)
1 001 01 0001 SH start of heading (soh)
...
... VÀ HƠN THẾ NỮA
Ngoài ra còn có luit
thiết bị dịch UTF-8 đầu cuối, pty
tôi đoán rằng nó hoạt động giữa các Xterm mà không có hỗ trợ UTF-8. Nó xử lý rất nhiều công tắc - chẳng hạn như ghi nhật ký tất cả các byte được chuyển đổi thành một tệp hoặc -c
dưới dạng một |pipe
bộ lọc đơn giản .
Tôi chưa bao giờ nhận ra có quá nhiều thứ này - bản đồ địa phương và nhân vật và tất cả những thứ đó. Đây rõ ràng là một vấn đề rất lớn nhưng tôi đoán tất cả diễn ra sau hậu trường. Có - ít nhất là trên hệ thống của tôi - vài trăm man 3
kết quả liên quan cho các tìm kiếm liên quan đến ngôn ngữ.
Và cũng có:
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
...
Điều đó sẽ diễn ra trong một thời gian rất dài.
Các Xlib
chức năng xử lý việc này mọi lúc - luit
là một phần của gói đó.
Các Tcl_uni...
chức năng có thể chứng minh là hữu ích là tốt.
chỉ cần <tab>
hoàn thành một chút và man
tìm kiếm và tôi đã học được khá nhiều về chủ đề này.
Với localedef
- bạn có thể biên dịch locales
trong I18N
thư mục của bạn . Đầu ra rất thú vị và không hữu ích lắm - không giống như charmaps
tất cả - nhưng bạn có thể nhận được định dạng thô giống như bạn chỉ định ở trên như tôi đã làm:
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
Sau đó, với od
bạn có thể đọc nó - byte và chuỗi:
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...<
...
Mặc dù đó là một chặng đường dài để giành chiến thắng trong một cuộc thi sắc đẹp, đó là đầu ra có thể sử dụng. Và od
là cấu hình như bạn muốn nó là tất nhiên.
Tôi đoán tôi cũng đã quên về những điều này:
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
Tôi có lẽ đã quên chúng vì tôi không thể khiến chúng làm việc. Tôi không bao giờ sử dụng Perl
và tôi không biết làm thế nào để tải một mô-đun đúng cách tôi đoán. Nhưng các man
trang trông khá đẹp. Trong mọi trường hợp, một cái gì đó cho tôi biết bạn sẽ thấy việc gọi mô-đun Perl ít nhất là khó khăn hơn một chút so với tôi. Và, một lần nữa, những thứ này đã có trên máy tính của tôi - và tôi thậm chí không bao giờ sử dụng Perl. Cũng có một số đáng chú ý I18N
mà tôi đã cuộn một cách thận trọng bằng cách biết rõ tôi cũng sẽ không làm cho họ làm việc.
/usr/share/i18n/locales/i18n
... tất nhiên phần lớn đến từ Cơ sở dữ liệu Ký tự Unicode. Tất nhiên, thật tuyệt khi có một mệnh lệnh