UnixコマンドラインからUnicode標準フォーマット間変換

UnixコマンドラインからUnicode標準フォーマット間変換

Unicodeでは、いくつかの文字の組み合わせに複数の表現があります。

たとえば、文字それは次のように表現できます。

  • コードポイントU + 00E4(c3 a4UTF-8エンコーディングの2バイト)である「ä」または
  • 「ä」は2つのコードポイントU + 0061 U + 0308(61 cc 88UTF-8の3バイト)です。

Unicode標準によると、両方の表現は同じですが、「正規化された形式」は異なります。UAX #15: Unicode 正規化形式

Unixツールボックスにはさまざまなテキスト変換ツールがあります。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標準ライブラリに関数を介してUnicode表現を翻訳できるモジュールがあります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文字を使用して文字列をUnicodeとしてマークする必要があります。

$ 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

関連情報