unix 명령 행에서 유니 코드 정규화 양식 간 변환 코드 포인트 U + 0061 U

유니 코드에서 일부 문자 조합에는 둘 이상의 표현이 있습니다.

예를 들어, 문자 ä 는 다음과 같이 나타낼 수 있습니다.

  • “ä”, 즉 코드 포인트 U + 00E4 ( c3 a4UTF-8 인코딩의 2 바이트 ) 또는
  • “ä”는 두 개의 코드 포인트 U + 0061 U + 0308입니다 ( 61 cc 88UTF-8의 3 바이트 ).

유니 코드 표준에 따르면 두 표현은 동일하지만 “정규화 형식”이 다릅니다 ( UAX # 15 : 유니 코드 정규화 형식 참조) .

유닉스 툴박스에는 sed , tr , iconv , Perl 등 모든 종류의 텍스트 변환 툴 이 있습니다. 명령 줄에서 빠르고 쉬운 NF 변환을 수행하려면 어떻게해야합니까?



답변

ICU 에서 uconv유틸리티를 사용할 수 있습니다 . 음역 ( )을 통해 정규화 를 수행합니다 .-x

$ uconv -x any-nfd <<<ä | hd
00000000  61 cc 88 0a                                       |a...|
00000004
$ uconv -x any-nfc <<<ä | hd
00000000  c3 a4 0a                                          |...|
00000003

데비안에서는 우분투 및 기타 파생 상품 uconvlibicu-dev패키지에 포함되어 있습니다. Fedora, Red Hat 및 기타 파생 제품 및 BSD 포트에서는 icu패키지에 있습니다.


답변

파이썬은 unicodedata표준 라이브러리에 모듈을 가지고 있으며 , unicodedata.normalize()함수 를 통해 유니 코드 표현을 번역 할 수 있습니다 :

import unicodedata

s1 = 'Spicy Jalape\u00f1o'
s2 = 'Spicy Jalapen\u0303o'

t1 = unicodedata.normalize('NFC', s1)
t2 = unicodedata.normalize('NFC', s2)
print(t1 == t2)
print(ascii(t1))

t3 = unicodedata.normalize('NFD', s1)
t4 = unicodedata.normalize('NFD', s2)
print(t3 == t4)
print(ascii(t3))

Python 3.x로 실행 :

$ python3 test.py
True
'Spicy Jalape\xf1o'
True
'Spicy Jalapen\u0303o'

파이썬은 쉘 하나의 라이너에는 적합하지 않지만 외부 스크립트를 만들고 싶지 않은 경우 수행 할 수 있습니다.

$ python3 -c $'import unicodedata\nprint(unicodedata.normalize("NFC", "ääääää"))'
ääääää

Python 2.x의 경우 인코딩 줄 ( # -*- coding: utf-8 -*-) 을 추가 하고 문자열을 u 문자로 유니 코드로 표시해야합니다.

$ python -c $'# -*- coding: utf-8 -*-\nimport unicodedata\nprint(unicodedata.normalize("NFC", u"ääääää"))'
ääääää


답변

hexdump 도구로 확인하십시오.

echo  -e "ä\c" |hexdump -C

00000000  61 cc 88                                          |a..|
00000003

iconv로 변환하고 hexdump로 다시 확인하십시오.

echo -e "ä\c" | iconv -f UTF-8-MAC -t UTF-8 |hexdump -C

00000000  c3 a4                                             |..|
00000002

printf '\xc3\xa4'
ä


답변

완전성을 위해 perl:

$ perl -CSA -MUnicode::Normalize=NFD -e 'print NFD($_) for @ARGV' $'\ue1' | uconv -x name
\N{LATIN SMALL LETTER A}\N{COMBINING ACUTE ACCENT}
$ perl -CSA -MUnicode::Normalize=NFC -e 'print NFC($_) for @ARGV' $'a\u301' | uconv -x name
\N{LATIN SMALL LETTER A WITH ACUTE}


답변

coreutils에는 적절한 패치가 있습니다 unorm. 4 바이트 wchars에서 나에게 잘 작동합니다. http://crashcourse.housegordon.org/coreutils-multibyte-support.html#unorm 따르십시오
나머지 문제는 2 바이트 wchar 시스템 (32 비트의 cygwin, windows, plus aix 및 solaris)이며 코드 포인트를 상단에서 변환해야합니다 대리 쌍으로 평면을 배치하고 그 반대도 마찬가지이며, 기본 libunistring / gnulib는 아직 처리 할 수 ​​없습니다.

perl에는 unicharscmdline에서 다양한 정규화 양식을 수행 하는 도구가 있습니다. http://search.cpan.org/dist/Unicode-Tussle/script/unichars


답변

Charlint라는 펄 유틸리티가 있습니다.

https://www.w3.org/International/charlint/

당신이 원하는 것을합니다. 또한 파일을 다운로드해야합니다.

ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt

첫 실행 후 Charlint가 해당 파일의 호환되지 않는 항목에 대해 불평하므로 유니 코드 데이터 .txt에서 해당 행을 삭제해야합니다.


답변