iconvファイルフォーマット変換
5322 ワード
多くのunixプラットフォームにはiconvツールがあり、文字符号化を変換することができます。通常のテキストファイルでは、fileコマンドを使用してファイルの文字符号化タイプを検出することができ、両者を組み合わせることで、未知の符号化タイプのテキストファイルを特定の符号化タイプで符号化することが非常に容易になります。
たとえば、linuxカーネルのソースコードの一部のファイル符号化はASCIIで符号化されていません(hackerの「奇妙な」名前に関係しているようです).たとえば、次のようにします.
$ cd/path/to/linux-2.6.17
$ file kernel/sys.c
kernel/sys.c: ISO-8859 C program text
このファイルの文字コードタイプはISO-8859であることがわかります.
ASCIIコードではないものを見て、iconvでASCIIから回してみましょう.
$ iconv -f ASCII -t UTF8 kernel/sys.c >/tmp/sys.c
iconv: illegal input sequence at position 29203
変換エラーが発生しました.29203バイトの文字コードはASCIIではありません.hexdumpとcatコマンドで、その位置が何なのかを確認します.
$ hexdump -C -n 10 -s 29203 kernel/sys.c
00007213 e5 20 73 76 65 6e 73 6b 61 2e |. svenska.|
0000721d
$ cat kernel/sys.c | grep svenska
* Samma p? svenska..
これはある作者の名前だろう.
次にfileコマンドで教えてくれたコードタイプISO-8859を変換し、まずiconv-lでiconvがISO-8859をサポートしているかどうかを確認しなければなりません.
$ iconv -l | grep ISO-8859
ISO-8859-1//
ISO-8859-2//
ISO-8859-3//
ISO-8859-4//
ISO-8859-5//
ISO-8859-6//
ISO-8859-7//
ISO-8859-8//
ISO-8859-9//
ISO-8859-9E//
ISO-8859-10//
ISO-8859-11//
ISO-8859-13//
ISO-8859-14//
ISO-8859-15//
ISO-8859-16//
明らかにサポートされていますが、ISO-8859は直接サポートされていないので、変換時にそのうちの1つを選択してみなければなりません.
$ iconv -f ISO-8859-1 -t UTF8 kernel/sys.c >/tmp/sys.c
ps:一例はdb 2がiso-8859形式であると仮定し、スクリプト処理を使用すると、原文はISO-8859形式ではない可能性があります.現在使用されています.
iconv -f ISO-8859-9 -t utf-8 $1.deliso > $1.delutf
iconv -f utf-8 -t ISO-8859-9 $1.delutf > $1.del
解決方法
変換後のファイルサイズと29203バイト付近の内容を見てみましょう.
$ ls -l kernel/sys.c/tmp/sys.c
-rwxr-xr-x 1 falcon falcon 50359 2006-06-18 09:49 kernel/sys.c
-rw-r--r-- 1 falcon falcon 50360 2008-06-29 14:06/tmp/sys.c
$ cat/tmp/sys.c | grep sven
* Samma på svenska..
まとめると、未知の文字符号化タイプのテキストファイルを指定した符号化タイプで再符号化したい場合は、どうすればいいのでしょうか.
1. ファイルの文字コードをfileコマンドで表示する
2. iconv-lでiconvがこの符号化タイプをサポートしているかどうかを確認し、サポートされている場合は、その中から最も近い試みを見つけます.
3. 可能な場合はiconvを有効にして変換します.そうしないとエラーが表示されます.
これにより、スクリプトを書いてこの変換プロセスを自動的に行うことができます(不完全で、自分でいくつかの内容を追加することができます).たとえば、次のようにします.
Code:
#!/bin/bash
#encode.sh -- encode a file with an indicated encoding
# make sure user give two arguments
[ "$#"!= 2 ] && echo "Usage: `basename $0` [to_encoding] [file]"&& exit -1
# make sure the second argument is a regular file
[ ! -f $2 ] && echo "the second argument should be a regular file "&& exit 1
file=$2
# make sure the first argument is a encoding supported by iconv
iconv -l | grep -q $1
[ $? -ne 0 ] && echo "iconv not support such encoding: $1"&& exit -1
to_encoding=$1
# is there a text file?
file_type=`file $file | grep "text$"`
[ $? -ne 0 ] && echo "$file is not a text file"&& exit -1
# get the old encoding
from_encoding=`echo $file_type | cut -d""-f 2`
from_encoding=`iconv -l | grep $from_encoding`
[ $? -ne 0 ] && echo "iconv not support the old encoding: $from_encoding"
from_encoding=`echo $from_encoding | cut -d"/"-f 1`
# convert the file from from_encoding to to_encoding
iconv -f $from_encoding -t $to_encoding $file
[Ctrl+A Select All]
ダウンロード後はencodeとして保存する.sh、実行可能権限を追加し、ファイルを変換してみます.
$ chmod +x encode.sh
$ ./encode.sh UTF8 kernel/sys.c
charset-detector:ファイル符号化を自動的に検出するプログラム
開発プログラムの前に、通常は動機がありますが、私が作ったばかりのこのプログラムについて言えば、「PCManX」を通じて対岸のBBSホームに接続するためです.残念ながら、私は面倒な問題に遭遇しました.自分でコードを指定しなければなりません.先週自転車に乗ったとき、手を握りすぎて軽微な怪我をしました.だから、字を間違えていました.Anyway、私は[PCManX]の代わりにBBS符号化を自動検出する機能を加えることにしました.自動推測ファイル符号化のアルゴリズムは、Mozillaの中ですでに良い実装があり、Mozillaの公式ページにも論文[A composite approach to language/encoding detection]を提供し、対岸のネットユーザーは簡体字中国語翻訳[言語/符号化検出の複合方法]を提供し、関連する実装はMozilla cvs tree[extensions/universalchardet]を参照することができる.以前のblog[Mozilla Re-licensing完了]でもMozilla Foundationがこのほど発表したように、Mozilla codebaseは元のMPL(Mozilla Public License)からMPL/GPL/LGPLの3重授権モードに変換され、「PCManX」の授権に適合しているため、どのように統合するかが急務だ.
私はNSPR(Mozilla Runtime)のような風呂敷を初歩的に取り除き、G++の-fno-rtti、-fno-exceptions、および-nostdinc++compilation flagsでコンパイルし、-lstdc++を-lsupc++に置き換えると、さらにC-only libraryを得ることができ、目標はadd-onを作成し、[PCManX]がdlopenを通じて内部の実装を操作することができ、自動検出ファイルの符号化とテストプログラムを初歩的に完成させることである.[charset-detector](bzip 2 tarball)という名前です.
以下、テストプログラム(testディレクトリの下に置く)を例に、動作状況を見てみましょう.initcall.txtはBig 5で符号化されたファイルです.
charset-detector/test$ file initcall.txt
initcall.txt: ISO-8859 English text, with CRLF line terminators
charset-detector/test$ ./test-chardetect ./initcall.txt
File ./initcall.txt ...
Charset = Big5
UNIXのツールfileは誤審しましたが、私たちのcharset-detectorはコードを正しく認識していますが、charset-detect libraryのAPIは6つしかなく、操作しやすいです.次はhack[PCManX]でBBS connectionを確立させた後、charset-detect APIsにbufferを渡して符号化の判断を行い、後で適度な画面再描画動作を行う.
jservからMay 22,2006 05:40 PMに発表