Unix 명령줄에서 유니코드 표준 형식 간 변환

Unix 명령줄에서 유니코드 표준 형식 간 변환

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

예를 들어, 문자그것은 다음과 같이 표현될 수 있다:

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

유니코드 표준에 따르면 두 표현은 동일하지만 "정규화된 형식"이 다릅니다.UAX #15: 유니코드 정규화된 형식.

유닉스 도구 상자에는 다양한 텍스트 변환 도구가 있습니다.sed,,, 나는 Perl을 생각했습니다. 명령줄에서 NF 변환을 빠르고 쉽게 수행하는 방법은 무엇입니까?

답변1

당신은 그것을 사용할 수 있습니다uconv유틸리티는 다음에서 비롯됩니다.중환자실.표준화음역( )을 통해 달성됩니다 -x.

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

Debian, Ubuntu 및 기타 파생 제품에서는 패키지 uconv에 있습니다 . libicu-devFedora, Red Hat 및 기타 파생 제품과 BSD 포트에서는 icu패키지에 포함되어 있습니다.

답변2

Python에는 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'

Python은 셸 문에 적합하지 않지만 외부 스크립트를 생성하지 않으려면 다음을 수행할 수 있습니다.

$ 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"ääääää"))'
ääääää

답변3

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'
ä

답변4

올바른 패치를 얻기 위한 coreutils용 패치가 있습니다 unorm. 4바이트 wchar에서 제대로 작동합니다. 따르다http://crashcourse.housegordon.org/coreutils-multibyte-support.html#unorm 남은 문제는 상위 평면 코드 포인트를 대리 쌍으로 또는 그 반대로 변환해야 하는 2바이트 wchar 시스템(32비트의 cygwin, windows, aix 및 Solaris)이며, 기본 libunistring/gnulib는 아직 처리할 수 없습니다. 이 문제.

나는 이 패치를 계속 유지하고 있습니다https://github.com/rurban/coreutils/tree/multibyte

Perl에는 unichars명령줄에서 다양한 형태의 정규화를 수행하는 도구도 있습니다.http://search.cpan.org/dist/Unicode-Tussle/script/unichars

관련 정보