▼ 2009/04/09(木) Python 文字コードの変換
poseたんが寺のランク計算プログラムってのを書いてたので、早速ダウンロードして使ってみることに。それでソースを眺めてみるとShift_JISなので文字化け。うちのターミナルはUTF-8だからな。まぁ、その辺のエディタで開けば色んな文字コードに対応してるから問題無いんだけど、やっぱりターミナル上で読みたいってのもあるし、それになにより何でもかんでもUTF-8にしたいってことで、Shift_JISなファイルやEUC-JPなファイルをUTF-8に変換するスクリプトを作ってみたので公開。最近、巷でプログラミングしてブログに載せるのが流行ってるみたいなので。
色んなOSが混在する環境だとやっぱ文字コードもバラバラになるからね。こいつを使ってUTF-8に変換しちゃいましょうって話です。まぁ、nkfとか使えばコマンドラインからさくっと出来るんだけど、あえてスクリプトで・・・みたいな。Pythonでやってみました。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# to_utf8.py
import os
import sys
import tempfile
import shutil
import pykf
def guess_charset(data):
c = pykf.guess(data)
if c is pykf.UTF8:
return 'utf-8'
elif c is pykf.EUC:
return 'euc-jp'
elif c is pykf.SJIS:
return 'shift_jis'
elif c is pykf.ASCII:
return 'ascii'
else:
print "Supported charset: utf-8, euc-jp, shift_jis, ascii"
sys.exit(1)
def to_utf8(data):
charset = guess_charset(data)
try:
u = data.decode(charset)
return u.encode('utf-8')
except TypeError, e:
print e
sys.exit(1)
def main():
source_file = os.path.abspath(sys.argv[1])
dest_dir, base_file = source_file.rsplit('/', 1)
ext = base_file.split('.')[-1]
dest_tmp = tempfile.mktemp(".%s", dir = dest_dir) % (ext)
input = open(source_file, 'rU')
output = open(dest_tmp, 'w')
data = input.read()
try:
utf8_data = to_utf8(data)
output.write(utf8_data)
finally:
input.close()
output.close()
shutil.move(source_file, "%s.bak" % (source_file))
shutil.move(dest_tmp, source_file)
if __name__ == '__main__':
if not len(sys.argv) == 2:
print "Usage: %s filename" % (sys.argv[0])
sys.exit(1)
main()
実行時にUTF-8に変換したいファイルを引数で与えてやればおk。実行すると元のファイルは元々あったディレクトリに.bakの拡張子をつけてバックアップされて、UTF-8に変換されたほうのファイルは元のファイルと同じ名前で作成される。使用例は以下のような感じ。
$ python to_utf8.py ~/tmp/RankCalc.java
これで、~/tmp/の下に、RankCalc.java, RankCalc.java.bak という2つのファイルが出来て、RankCalc.javaのほうがUTF-8になってて、RankCalc.java.bakは元々のファイルになる。大切なことを書き忘れてたけど、pykfというモジュールを使ってるのでこいつをインストールしてやらないといけない。
$ wget http://archives.sertice.org/devs/linux/cvs/pykf-0.3.4.tgz $ tar xvfz pykf-0.3.4.tgz $ cd pykf-0.3.4 $ python setup.py build $ sudo python setup.py install
ちなみにエラー処理とか気にせず同じようなことをRubyでやる場合はめちゃくちゃ簡単にできる。
#!/usr/bin/ruby -i.bak require "kconv" while line = ARGF.gets print Kconv.toutf8(line) end
参考サイト:
- TB-URL http://chibilog.name/0359/tb/
