背景:我有一项工作任务是将svn某目录日常更新的sql文件(归类到日期命名的文件夹中)拿到数据库中执行。
一开始,我是先把sql文件update下来,用notepad++打开,拷贝每一个文本的sql语句,放到plsql中执行。虽然现在只有几个,我手动执行没有问题,但是我想以后有一天sql文件有几十或者上百呢...
我办公用的电脑是win10,cmd下的我想到了用copy *.sql > all.sql,如此合并之后all.sql有中文乱码,后来问同事才知道那个SVN目录下是开发提交的sql脚本,有gbk、utf8、gb2312等各种格式,已无力吐槽(涉及到公司的内容,图就不贴了)。
然后我就上网各种查cmd下是否有字符集转换的命令,网友给我说了这个win_iconv,但是在linux下iconv也要知道原字符集才能转啊。
于是,我觉定要动手搞下python了,一边上网查一遍自己尝试,这是最终版本:
mergeSql.py
import os,sysimport chardetreload(sys)sys.setdefaultencoding("gbk")fType_input = sys.argv[1]fileName_input = sys.argv[2]def mergeSql(fdir,fType,outfile): if os.path.exists(fileName_input): os.remove(fileName_input) file_list = os.listdir(fdir) file_to_write = file(outfile,'w') for f in file_list: if str(f).split(".")[-1] == fType: file_to_read = file(fdir+str(f),'r') file_to_write.write('\r\n/*----'+str(f)+'----*/\r\n') print 'merge...'+str(f) while True: line = file_to_read.readline() encoding = chardet.detect(line)['encoding'] if len(line) == 0: break else: line = line.decode(encoding).encode('utf-8') file_to_write.write(line.decode('utf-8').encode('gbk')) file_to_read.close() file_to_write.write('\r\nexit;'.decode('utf-8').encode('gbk')) ##这里加在sql最后用于退出sqlplus file_to_write.close()mergeSql('./',fType_input,fileName_input)
当然,还得先安装第三方模块,pip install chardet。
上一个版本还是蛮土的,长这样:
line = file_to_read.readline()encoding = chardet.detect(line)['encoding']if encoding == 'ascii': line = line.decode('ascii').encode('utf-8')elif encoding == 'utf-8': passelif encoding == 'GB2312': line = line.decode('GB2312').encode('utf-8')这样子不好,就只能处理三种字符集;不要问我为什么不直接转换为gbk,我也不知道为什么,直接转报错了,先统一转换为utf-8再转换为gbk是ok的!
最后,要结合sqlplus才能一键执行:
run.bat
python mergeSql.py sql all.sqlsqlplus [email protected] @all.sql > all.logpause
mergeSql.py 要传两个参数,python mergeSql.py arg1 args2
arg1是处理的文件名后缀,arg2是合并生成的文件(脚本运行时,如果这个文件存在则删除)。
另:转为gbk是因为sqlplus和cmd的编码字符集都是gbk,如果是其他字符集则cmd窗口看到的是中文乱码。
现在这项工作就变成先update,之后双击下run.bat,最后看下all.log执行日志完事!
版权声明:本文为博主原创文章,未经博主允许不得转载。