aharenchi's blog

年1回ペースで更新してます

指定ディレクトリ以下の「Shift-JISコード」を「UTF-8コード」に変換するスクリプト

Webサイトを十数年近く運用していると、昔作成したWebページを久しぶりに開いてみると文字化けしてたりってありますよね..?

大体の場合が、メタタグの文字コードがShift-JISなので文字化けしているので、UTF-8に変換すると治ります。

だけど、Shift-JISコードのHTMLファイルが、どのディレクトリにどれだけあるか分からないというカオスな状態......あったり.....基本はなかったりすると思います。私はありました。

いちいち、HTMLファイルを調べて、「Shift-JISコード」を「UTF-8コード」に書き換えるのは苦行だったので、

指定したディレクトリ以下の「Shift-JISコード」と「UTF-8コード」を変換するスクリプトをpython2とシェルで作りました。

pythonだとこんな感じ。

#coding: UTF-8
import sys
import shutil
import os
import re
import nkf

argvs = sys.argv  # コマンドライン引数リスト
argc = len(argvs) # 引数の個数

# 引数チェック
if (argc != 2):
    print 'prease type "python %s directory_path"' %argvs[0]
    sys.exit()

r_path = argvs[1] # 指定ディレクトリ 
target_word = 'charset=Shift_JIS' # ファイル内の置換元文字列 
new_word = 'charset=UTF-8' # ファイル内の置換後文字列
r_ext = '.html' # ファイルの拡張子を指定  

# 指定ディレクトリ以下のファイル情報を取得
def find_all_files(directory):
    for root, dirs, files in os.walk(directory):
        yield root
        for file_name in files:
            yield os.path.join(root, file_name)

if __name__ == "__main__":

    # ディレクトリ内から該当文字列を検索 
    for file_name in find_all_files(r_path):

        root,ext= os.path.splitext(file_name)
    
        if ext == r_ext: # 指定拡張子で検索          

            # 検索初期化
            re_flag = False
            line_list = []
            
            with open(file_name,'r') as f_in:                
                # ファイル内を一行ずつ検索
                for l in f_in.readlines():
                    line = nkf.nkf('-w8',l) # 文字コードはUTF-8にする             

                    if target_word in line: # 置換元文字列があった場合
                        re_flag = True # フラグON
                        new_line = line.replace(target_word,new_word) # 置換
                        line_list.append(new_line) # 書き込み   

                    else: # 置換元文字列がない場合
                        line_list.append(line) # 書き込み
                    

            # 置換元文字列があった場合  
            if re_flag:                
                print file_name # 編集ファイル名表示

                # バックアップ作成
                bnk_f = root + "_bnk.html"
                shutil.copyfile(file_name,bnk_f)

                # ファイル書き込み
                with open(file_name,'w') as f_out:
                    for row in line_list:
                        f_out.write(row)

シェルスクリプトだとこんな感じ。短い。

if [ $# -ne 1 ]; then
  echo "prease type sh chang_content.sh  directory_path"
  exit 1
fi

	
for file_name in `find $1 -type f  -name '*.html'`			   
do
   sed -i -e 's/Shift_JIS/UTF-8/' ${file_name} # テキストの書き換え
   nkf --overwrite -wLu ${file_name} # 文字コードを変換
done


次は、文字化け修正後の確認・表示崩れのチェッカーを作成することですかね..?
diffコマンドでもいいのか?しっかり目視したらいいのか?難しいところ。

本当は、カオスなWebサイト構造をどうにかしたいよ〜ひぃ〜ん。

スペシャルさんくす
nkfについてアドバイスをくれたあっとんさん(@_atton)
pythonのコードレビューをしてくれたまえけん(@maeken2010)
に感謝!感謝です!

参考にしたページ
Pythonで再帰的にファイル・ディレクトリを探して出力する - Qiita

追記
あっとんがブログに書いてくれてました!
attonblog.blogspot.jp