SQL Serverからエクスポートしたrpt形式ファイルを渡され、
CSVに変換してくれと依頼される。
「あれ、SQL Server Management Studioに
直接CSV出力する機能ありませんでしたっけ?」
と確認しても「しらん。やれ。」と言われる。
そんなよくある状況で助けてくれるrpt2csv変換スクリプトを作成した。
SQL Serverが吐くもの以外でrpt形式のファイルは見たことがないが、
中身は下記のような形式になっている:
カラム名1 カラム名2 カラム名3 ... --------- ---------- ---------- ... 値1-1 値1-2 値1-3 ... 値2-1 値2-2 値2-3 ...
1行目がカラム名、
2行目がスペース区切りでハイフンがカラムサイズ分ずつ並び、
3行目以降がカラムサイズ分ずつスペース埋めでデータが並ぶ
フォーマットになっているようだ。
2行目でハイフンの数を元にカラムごとのサイズを取得し、
それを元に3行目以降のデータをカラムサイズごとに切り出し、
スペースをtrimすればデータを取り出すことができそうだ。
スクリプトを作成する
言語はPython3。2でも動くかな?
ファイルから1行ずつデータを取得するとして、
それぞれの行(カラム名行、ハイフン行、データ行)のデータを
変換する関数を作っていく。
1行目のカラム名行は、
連続するスペースを1つにしてからスペースで分割してリストにする。
import re def create_header_list(line): line = re.sub(r'\s+', ' ', line) return line.split(" ")
2行目のハイフン行は、
スペースで分割してハイフンの文字数を取得して
カラム別文字数リストにする。
def create_length_list(line): col_list = line.split(" ") return [len(x) for x in col_list]
3行目以降のデータ行は、
2行目から生成したカラム別文字数リストを使って、
先頭から順番に文字数分ずつ部分文字列を切り出していく。
スペース埋めされているので、trimして、リストにまとめる。
def create_data_list(line, length_list): data_list = [] char_index = 0 for length in length_list: new_length = char_index + length chunk = line[char_index:new_length].strip() data_list.append(chunk) char_index += length + 1 return data_list
行データをリストにしてしまえば、Pythonのcsvモジュールで
簡単にCSV化して出力できる。
rptファイルを読み込んでcsvファイルを出力するメイン処理を加えて、
全体として下記のようなスクリプトになった。
rptファイルの文字コードがBOM付きutf-8だったので、
読み込み時のエンコードを「utf-8-sig」と指定している。
rpt2csv.py
# -*- coding: utf-8 -*- import re import csv rpt_file_path = "<rptファイルのパス>" csv_file_path = "<csvファイルの出力先パス>" def create_header_list(line): line = re.sub(r'\s+', ' ', line) return line.split(" ") def create_length_list(line): col_list = line.split(" ") return [len(x) for x in col_list] def create_data_list(line, length_list): data_list = [] char_index = 0 for length in length_list: new_length = char_index + length chunk = line[char_index:new_length].strip() data_list.append(chunk) char_index += length + 1 return data_list line_number = 0 header_list = [] length_list = [] with open(rpt_file_path, encoding="utf-8-sig") as rpt_file: with open(csv_file_path, "w", newline='', encoding="cp932") as out_csv_file: writer = csv.writer(out_csv_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL) for line in rpt_file: line_number += 1 if line_number == 1: header_list = create_header_list(line) writer.writerow(header_list) continue if line_number == 2: length_list = create_length_list(line) continue data_list = create_data_list(line, length_list) writer.writerow(data_list)
おわり
楽しく書けたけど、
このスクリプトを再利用する機会が来るのかどうか、疑問。
SQLServer2014データベース構築・管理ガイドEnterprise対応
- 作者: 長岡秀明
- 出版社/メーカー: 秀和システム
- 発売日: 2015/08/31
- メディア: 単行本
- この商品を含むブログを見る