こうかの雑記

こうかの雑記

昔の懐かしいこと、ubuntuのこと、その他いろいろ

pythonでテキストファイルのエンコード変換

 ダウンロードしたテキストファイルが自分が使っているシステムと違うエンコードがされている場合があります。ubuntu(linux)はデフォルト・エンコードutf-8なのですが、銀行やカード会社からダウンロードしたcsvファイルはShift-jisになっています。大部分の利用者がWindowsですからね。

 これをlibreofficeのCalc(Excel相当のもの)にインポートする時、わざわざエンコード指示を変えてやらないと文字化けしてしまいます。なのでダウンロードした後utf-8に変換して保管するようにしました。

 エンコードを変換くらいなら、わざわざpythonで書かなくても端末画面に慣れた人なら、iconvコマンド、knfコマンドを使えば簡単にできるのですが、今回はpythonスクリプトを書きました。 コマンドの場合、オプションをすぐに忘れてしまうのでね。

 pythonスクリプトではテキストファイルのエンコードを調べて、iso-2022-jp euc-jp shift_jisだったらutf-8に変換、またはutf-8だったらshift_jisに変換しています。

 実行すると、対象ファイルの選択画面が表示されます。選択すると、同じフォルダー上にエンコード名を付加したファイル名が作られます。元のファイルは残ります。

エンコード変換スクリプト

#! /usr/bin/env python3
"""
    chg_encode.py
"""
import tkinter.filedialog
import tkinter.messagebox
import codecs
import sys
import os

def convert(inpath, incode, outpath, outcode):
    try:
        inf = codecs.open(inpath, "r", incode)
        outf = codecs.open(outpath, "w", outcode)
    except Exception as err:
        sys.stderr.write("*** error ***\n")
        sys.stderr.write(str(err) + '\n')
        sys.exit( )
    for row in inf:
        outf.write(row)
    inf.close()
    outf.close()

def set_file_path():
    root = tkinter.Tk() 
    root.withdraw()
    tkinter.messagebox.showinfo('chg_encode.py','入力ファイルを選択してください!')
    inpath = tkinter.filedialog.askopenfilename(title='chg_encode.py')
    root.destroy()
    return(inpath)

''' エンコードを調べる。
   参考url:https://qiita.com/ty21ky/items/942e8f46441b092fce29
     オリジナルのブログは既に無くなっていた。'''
def getEncode(filepath):
    encs = "iso-2022-jp euc-jp shift_jis utf-8".split()
    for enc in encs:
        with open(filepath, encoding=enc) as fr:
            try:
                fr = fr.read()
            except UnicodeDecodeError:
                continue
        return enc  # 該当あり
    return('')  # 該当なし

def main():
    inpath = set_file_path()
    if inpath != '':
        files = (inpath,)
    else:
        sys.stderr.write('ファイル選択なし')
        sys.exit( )

    in_encode=getEncode(inpath)
    if in_encode == '':
        sys.stderr.write('encode判定出来ず')
    else:
        if in_encode == 'utf-8':
            out_encode = 'shift_jis'
        else:
            out_encode = 'utf-8'
    w_fname = os.path.splitext(inpath)
    outpath = w_fname[0] + '_' + out_encode + '.csv'

    convert(inpath, in_encode, outpath, out_encode)
    print('{:s} → {:s}'.format(inpath, outpath))
if __name__ == '__main__':
    main()
    input('Hit Enter-key')