複数のファイルをマージする
1.概要
パソコンで色んなデータを扱う場合、複数ファイルの連結(マージ)する作業は比較的多いと思います。
筆者の場合は、Excel VBAやPythonなどで作成したスクレイピングプログラムでWeb上から収集したデータを
CSVなどに出力して加工する場合も多いです。このようなデータを蓄積して1つのファイルに連結(マージ)後、
DB(データベース)を新規作成して、初期インポート用のファイルとして利用しています。
定期的に決まったフォーマットで同じ作業のものは、簡単なバッチファイル(bat)を作って実行させています。
バッチファイルは、WMI(Windows Management Instrumentation)やPower Shellの登場で枯れた技術のように
思われがちですが、企業のIT部門などでは、まだまだ、広く利用されていて現役で活躍しています。
手軽で簡単であり、高速性を求めなければ便利ですね。ただ、会社なとでバッチファイルを他の人に使わせようとした時に、
マージ対象とするファイルやディレクリ―が変更となった場合やマージ後の出力ファイル名が他のシステムと
関連していたりすると、当然変更が必要となるため、その都度、作成者が面倒を見ることになります。
そのような事情から、他の人が使うことを前提とした場合は、GUIで操作画面がある実行形式(exe)のツール
があった方が便利です。今回は、筆者が作成したマージツールを紹介します。
2.ファイルマージツール
2-1.ソースコード 概要で説明しましたが、バッチファイルによる簡単なサンプルを載せておきます。下記のサンプルですが、 必要に応じて、9行目のタイトル名と17行目の処理対象ファイルの拡張子(ワイルドカード)とマージ後の出力ファイル名 を適時修正して利用して下さい。マージ対象ファイルが格納されているディレクトリーは指定していませんので、 追加するか、同一ディレクリ―にバッチファイルを置いて実行させて下さい。どこにでもある簡単なものですみません。 雛形として利用して頂けたらと思います。バッチの命令としては、type命令かcopy命令で同等の処理ができますが、 copy命令の方がやや高速に処理できるようです。
URL : http://hsp.tv/index2.html 下記のリストは、今回紹介するテキストファイルマージツール(tfmarge)のHSPのソースコード(HSPユーザー向け)です。 HSPの開発環境を構築している人は、HSPのスクリプトエディタに読み込み、実行して見て下さい。 HSPの開発環境をインストールしていない場合は、HSP公式サイトから入手して下さい。 マージ処理は、bload命令とbsave命令によるファイルのオフセット値を指定しての読み込みと書き込み による処理のため、比較的高速な処理が実現できています。一応、バイナリーデータもマージ可能です。
ダウンロード
2.ファイルマージツール
2-1.ソースコード 概要で説明しましたが、バッチファイルによる簡単なサンプルを載せておきます。下記のサンプルですが、 必要に応じて、9行目のタイトル名と17行目の処理対象ファイルの拡張子(ワイルドカード)とマージ後の出力ファイル名 を適時修正して利用して下さい。マージ対象ファイルが格納されているディレクトリーは指定していませんので、 追加するか、同一ディレクリ―にバッチファイルを置いて実行させて下さい。どこにでもある簡単なものですみません。 雛形として利用して頂けたらと思います。バッチの命令としては、type命令かcopy命令で同等の処理ができますが、 copy命令の方がやや高速に処理できるようです。
@echo off setlocal cd /d %~dp0 echo. echo. echo *********************************************************** echo. echo CSVファイルのマージ処理 echo. echo. echo *********************************************************** echo. echo. rem ***** マージ開始 ***** copy *.csv > CSVマージ済み.csv echo 処理が完了しました。何かキーを押してください。 echo. pause >nul endlocal exit続いて紹介するのが、テキストファイルマージツールです。プログラム言語は、HSP(Hot soup Processer)3.51で 作成しています。HSPとは、20年以上前からサポートが続けられて進化している国産のスクリプト言語です。 最近では、M-1グランプリで優勝したマジカルラブリーの野田クリスタルさんが自作ゲームの開発に利用していることが 話題となり、再び注目されています。HSPに興味がありましたら、下記の公式サイトを覗いてみて下さい。 筆者もちょつとしたツールやアクセサリーなどを開発するのに20年以上前から愛用しています。 プログラミング言語HSP公式サイト : HSPTV
URL : http://hsp.tv/index2.html 下記のリストは、今回紹介するテキストファイルマージツール(tfmarge)のHSPのソースコード(HSPユーザー向け)です。 HSPの開発環境を構築している人は、HSPのスクリプトエディタに読み込み、実行して見て下さい。 HSPの開発環境をインストールしていない場合は、HSP公式サイトから入手して下さい。 マージ処理は、bload命令とbsave命令によるファイルのオフセット値を指定しての読み込みと書き込み による処理のため、比較的高速な処理が実現できています。一応、バイナリーデータもマージ可能です。
;***** テキストファイルマージ (tfmarge.hsp) *****
;***** 実行ファイル自動作成 ****
#packopt type 0
#packopt name "tfmarge"
#packopt runtime "hsprt"
#packopt hide 1
;***** notepad命令形式文字列ソート *****
#module
#uselib "kernel32.dll"
#cfunc lstrcmp "lstrcmpA" int,int
#deffunc ntsort var buf,int flag
sdim buf2,99999
notesel buf : max=notemax
repeat max
sdim temp,256
notesel buf : noteget temp,cnt
repeat max
sdim temp2,256
notesel buf2 : noteget temp2,cnt
if temp2="" : noteadd temp,cnt : break
ret=lstrcmp(varptr(temp),varptr(temp2))
if flag=0{
if ret<0 { ;昇順
noteadd temp,cnt
break
}
}else{
if ret>0 { ;降順
noteadd temp,cnt
break
}
}
loop
loop
buf=buf2
return
#global
#ifndef xdim
#uselib "kernel32.dll"
#func global VirtualProtect@_xdim "VirtualProtect" var,int,int,var
#define global xdim(%1,%2) dim %1,%2: VirtualProtect@_xdim %1,%2*4,$40,x@_xdim
#endif
#module
#uselib "ole32.dll"
#func CoTaskMemFree "CoTaskMemFree" int
#uselib "shell32.dll"
#cfunc SHBrowseForFolder "SHBrowseForFolderA" int
#cfunc SHGetPathFromIDList "SHGetPathFromIDListA" int,int
#uselib "user32.dll"
#func SendMessage "SendMessageA" int,int,int,int
#deffunc BrowseFolder str _szTitle, str _defaultfolder
szTitle = _szTitle : inifldr = _defaultfolder : sdim retfldr, 260 : xdim fncode, 8
fncode = $08247c83,$8b147501,$ff102444,$68016a30,$00000466,$102474ff,$330450ff,$0010c2c0
hbdata = varptr(inifldr), varptr(SendMessage)
BROWSEINFO = hwnd, 0, varptr(retfldr), varptr(szTitle), 3, varptr(fncode), varptr(hbdata), 0
pidl = SHBrowseForFolder(varptr(BROWSEINFO))
fret = SHGetPathFromIDList(pidl,varptr(retfldr))
CoTaskMemFree pidl
mref stt,64 : stt = fret
return retfldr
#global
#uselib "comctl32.dll"
#func InitCommonControlsEx "InitCommonControlsEx" sptr
#cfunc CreateStatusWindow "CreateStatusWindow" int,sptr,int,int
#uselib "user32.dll"
#func DestroyWindow "DestroyWindow" int
#func InvalidateRect "InvalidateRect" int,int,int
#func GetWindowRect "GetWindowRect" int,var
#define VER_TFAPPRI 1.0
#define MAXPATH 260
#define CB_GETLBTEXT $00000148
#define EM_SETMARGINS $000000D3
#define EC_LEFTMARGIN $00000001
#define EC_RIGHTMARGIN $00000002
#define SB_SETTEXT $00000401
#define ctype MAKELONG(%1,%2) (%1&$ffff|(%2<<16))
sdim instdir, MAXPATH
sdim genename,MAXPATH
sdim Folder, MAXPATH
sdim tmpstr,64
sdim s,1024*5
sdim buf
sdim cb
sdim temp
sdim outname,48
;***** 起動ディレクトリ取得 *****
if hspstat&1=0 { instdir=dirinfo(1)+"¥¥" : chdir dirinfo(1)
} else {
instdir=dirinfo(0)+"¥¥"
}
;***** GUI画面作成 *****
screen 0,580,200,0
sysfont 17 : syscolor 8
BarName="テキストファイルマージ Ver"+strf("%.1f",VER_TFAPPRI)+" (tfmarge)"
title BarName
font "Meiryo UI",12,0 : objmode 2
color 0,0,0 : pos 11,15 : mes "対象先"
pos 55,11 : input Folder,400,20
sendmsg objinfo(0,2), EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN,MAKELONG(2,0)
objsize 46,24 : pos 459,8: button "参照", *dirset
wcard="*.*¥n*.txt¥n*.dat¥n*.csv¥n*.htm¥n*.html¥n*.css¥n*.xml¥n*.log"
pos 11,43 : mes "拡張子"
font "Meiryo UI",14,0 : objmode 2
n=1 : objsize 80,24 : pos 55,38: combox n,120,wcard
font "Meiryo UI",12,0 : objmode 2
pos 150,43 : mes "出力ファイル名"
font "Meiryo UI",12,0 : objmode 2
pos 235,40 : input outname,220,20
sendmsg objinfo(3,2), EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN,MAKELONG(2,0)
objsize 46,24 : pos 459,37: button gosub "自動", *autoname
objsize 60,50 : pos 510,11: button "マージ", *marge
;***** StatusBar object setting *****
gosub *statusGen
gosub *statusMsg
gosub *statusstring
gsel 0,1
;***** 割込み処理 *****
onexit goto *owari
onclick gosub *msgclr
stop
*dirset
;***** フォルダ選択ダイアログを起動 *****
BrowseFolder "フォルダを選択してください", dir_cur
if stat {
Folder = refstr+"¥¥"
}
objprm 0,Folder
stop
*autoname
;***** 日付時刻をファイル名と仮設定する *****
outname =str(gettime(0))
outname+=strf("%02d",gettime(1))
outname+=strf("%02d",gettime(3))
outname+=strf("%02d",gettime(4))
outname+=strf("%02d",gettime(5))
outname+=strf("%02d",gettime(6))
;コンボボックスの選択文字列を取得(拡張子)
sendmsg objinfo(2,2),CB_GETLBTEXT,n,varptr(temp)
p=strlen(temp)
outname+=strmid(temp,1,p-1)
objprm 3,outname
return
*statusMsg
;***** ステータスバー初期メッセージ *****
String=" ファイルマージ(連結)する対象先ディレクトリを指定して下さい。"
return
*statusGen
;***** ステータスバーを作成 *****
InitCommonControlsEx icx : String=""
stshwnd=CreateStatusWindow($50000803,String,hwnd,0)
InvalidateRect stshwnd,0,1
dim rc,4 : GetWindowRect stshwnd,rc : sh = rc(3)-rc(1)
return
*statusstring
;***** ステータスバーに文字列を設定 *****
sendmsg stshwnd,SB_SETTEXT,0,varptr(String)
return
*msgclr
;***** メッセージクリア *****
color 255,255,255 : boxf 19,109,320,122 : color 0,0,0
return
*marge
;***** マージ処理開始 *****
gosub *msgclr
if Folder="" {
dialog "ファイルマージする対象フォルダを指定して下さい。",0
stop
}
chdir Folder
; 指定ディレクトリのファイル名のみを取得
sendmsg objinfo(2,2),CB_GETLBTEXT,n,varptr(cb)
dirlist s,cb,1 : num=stat
; ファイル名を五十音別に昇順ソート
ntsort s, 0
; 出力ファイルの空の実体を作成する
notesel buf
if outname="" {
String=" 出力ファイル名が省略されたので、日付時刻のファイル名を仮設定しました。"
gosub *statusstring
gosub *autoname
}
genename=Folder+outname
notesave genename
notesel s
; 1個目のファイルをマージする
noteget tmpstr,0
exist Folder+tmpstr
if strsize=-1 {
dialog "指定したディレクトリにはファイルがありません。",0 : stop
}
sdim filebuf,strsize
bload Folder+tmpstr,filebuf,strsize
bsave genename,filebuf,strsize,0
offset=strsize
; n個目のファイルをマージする
repeat num,1
noteget tmpstr,cnt
exist Folder+tmpstr : sdim filebuf,strsize
if strsize=-1 : break
bload Folder+tmpstr,filebuf,strsize
bsave genename,filebuf,strsize,offset
fsize =strsize : offset+=fsize
loop
exist genename
pos 20,110 : mes "ファイルのマージ処理が完了しました。"+" "+strsize+"byte"
outname = ""
gosub *statusMsg
gosub *statusstring
stop
*owari
;***** 終了処理 *****
onexit 0
DestroyWindow stshwnd
end
2-2.ツールの使い方
テキストファイルマージツール(tfmarge)の使い方です。ツールをダウンロードしたら、任意の場所で解凍して下さい。
-
(1)tfmarge.exeをダブルクリックして起動させます。
-
(2)連結(マージ)対象のファイルが格納されているディレクリ―を参照ボタンをクリックして
選択します。
(3)拡張子をプルダウンよりクリックして選択します。
(4)マージ後の出力ファイル名(拡張子含む)を入力します。自動ボタンをクリックすると
日付時刻形式のファイル名が作成されます。※省略時も同じです。
(5)マージボタンをクリックしてマージ処理を実行します。
-
(5)マージ対象ファイル数や容量にも依りますが、比較的高速に処理されます。
完了後、tfmarge.exeを閉じて下さい。
ダウンロード




コメント
コメントを投稿