import sys
import os
import glob
#文字列変換クラス
class ConvString():
def __init__(self):
self.err_count = 0
# 文字コードをUTF-8からSJISに変換する
# 戻り値 None :全文字がUTF8からSJISに変換完了
# 戻り値 None以外 :UTF8からSJISに変換できない文字があるため、変換不能文字を(N)に置換
def convert(self,str_in):
#1文字ずつ文字コードを変換する。
out_str = ""
err_flag = False
for i in range(len(str_in)):
try:
en = str_in[i].encode("cp932")
cv = en.decode("cp932")
except Exception as e:
#変換エラー
self.err_count += 1
err_flag = True
cvt = "(" + str(self.err_count) + ")"
out_str += cvt
else:
out_str += str_in[i]
if err_flag == False:
return None
else:
return out_str
#ログファイルオープン
def log_open():
global log_fp
log_fp = open("./log.txt","w",encoding="utf8")
#画面とログファイルの両方に出力する
def log_print(msg):
global log_fp
print(msg)
log_fp.write(msg+"\n")
#ログファイルクローズ
def log_close():
global log_fp
log_fp.close()
args = sys.argv
if len(args) != 3:
print("指定されたディレクトリ下のファイルについて再帰的に以下の処理行う")
print(f"{args[0]} P1 P2")
print("P1:機能コード")
print(" list :SJISに変換できないファイルの一覧を出力する")
print(" exec :SJISに変換できないファイルをSJISに変換可能なファイルにリネームする")
print("P2:ディレクトリ名")
#機能コードチェック
func = 0
if args[1] == "list":
func = 1
elif args[1] == "exec":
func = 2
else:
print("機能コードエラー")
#ディレクトリ名チェック
adir = os.path.abspath(args[2])
if os.path.isdir(adir) == False:
print(f"<{args[2]}> そのようなディレクトリはありません")
file_count = 0
ren_count = 0
err_count = 0
err_files = []
log_fp = None
log_open()
#文字列変換クラス生成
conv = ConvString()
#指定フォルダ下の全ファイルを取得
path = adir + '/**/*'
files = glob.glob(path,recursive=True)
#個々のファイルの処理を行う
for file in files:
#ファイルの完全パスを取得
apath = os.path.abspath(file)
#取得したパスがファイル名ならファイル名の変換を行う
if os.path.isfile(apath) == True:
#ファイル名部分を取得
file_name = os.path.basename(apath)
#ディレクトリ名部分を取得
dir_name = os.path.dirname(apath)
#ファイル名をUTF-8からSJISに変換する
result = conv.convert(file_name)
#変換不能文字が存在する場合、以下の処理を行う
if result != None:
#変換後のファイル名の完全パスを作成
apath_new = dir_name + "\\" + result
#変換後のファイルが既に存在するならエラーメッセージを追記
err_msg = ""
if os.path.exists(apath_new) == True:
err_msg = "変更後のファイル名が存在します"
#listの場合
if func == 1:
#画面に表示して、次の処理へ
if file_count == 0:
log_print("chcp 65001")
log_print(f'rename\t"{apath}"\t"{result}"\t{err_msg}')
file_count += 1
continue
#execの場合
msg = f"{apath}\t==>\t{result}"
#変更後のファイルが既に存在するならリネームせず、次の処理へ
if os.path.exists(apath_new) == True:
err_files.append(msg)
err_count += 1
continue
#リネーム実行
#リネーム完了メッセージ
log_print(msg)
ren_count += 1
#list又はbatchの場合
if func == 1:
log_print(f"処理終了 リネーム対象となるファイル件数={file_count}")
log_close()
#exec指定ありの場合
log_print(f"処理終了 リネーム件数={ren_count}")
if err_count > 0:
log_print(f"以下の{err_count}件のファイルがリネームできませんでした")
for fname in err_files:
log_print(fname)
log_close()