前回の続きですが、もうちょい付け足したかったので。
Tera Term 4.67以降が必要です。
今回は次のようなCSVファイルを使います。
ホスト名,コマンドファイル名
セパレータは「,」、ホスト名は接続するホストでコマンドファイル名はコマンドが羅列されたファイルで、このファイルからコマンドを読み込んで接続先のホストで実行するという動作を想定します。
文字列を分割する
文字列を分割するためにはstrsplitコマンドを使います。このコマンドはTera Term 4.67以降で使う事ができます。使い方は簡単で、セパレータと分割したい文字列を指定するだけです。
strsplit <strval> <separator> [<count>]
strvalは分割したい文字列、separatorはセパレータでCSVならば大抵は「,」です。countは分割したい最大数で、これは省略できます。
分割された文字列はシステム変数groupmatchstr1~groupmatchstr9へそれぞれ格納されます。分割された数はシステム変数resultへ格納されます。もしも分割数が9を超える場合は、システム変数resultには10が格納されます。
分割された文字列の行方
引数「count」を設定するか否かによって挙動が変わるので注意してください。
countを設定した場合
指定できるcountの最大数は9で、分割された数がcountに満たない場合は残りのgroupmatchstrNには空文字(””)が格納され、分割された数がcountを超える場合は残り全ての文字列が格納されます。
たとえば「a,b,c」といった文字列でcountに2を指定するとgroupmatchstr1には「a」、groupmatchstr2には「b,c」が格納されます。countに5を指定するとgroupmatchstr4とgroupmatchstr5には空文字(””)が格納されます。
countを指定しない場合
countを指定しない場合は分割する最大数を9とみなします。ただし、countに9を指定した場合との挙動に違いがあり、それは分割数が9を超えた場合です。
countを9に指定した場合、分割数が9を超えるとgroupmatchstr9には残り全ての文字列が格納されますが、countを指定しない場合は9番目に分割された文字列が格納され、残りの文字列は切り捨てられます。
システム変数resultはcountを指定しても指定しなくても変わりません。
CSVファイルを読み込んで分割する例
百聞は一見に如かず、という事でサンプルを掲載します。読み込むCSVファイルは次のようなものです。
host1,cmd1.txt "host2","cmd2.txt" 'host3','cmd3.txt'
このCSVファイルを読み込んで分割し、表示させてみます。
csvfile = "test.csv" separator = "," fileopen fh_csvfile csvfile 0 if fh_csvfile == -1 then messagebox 'csvファイルを開けません' 'エラー' endif while 1 ; ファイルから1行読む filereadln fh_csvfile csvbuf ; 最後まで読み込んだら終了 if result then break endif strsplit csvbuf separator 2 sprintf '[%s][%s]' groupmatchstr1 groupmatchstr2 messagebox inputstr csvbuf endwhile
これ、実行すると分かりますが、ちょっと気になるところがあります。というのも、ダブルクォーテーション(”)、シングルクォーテーション(’)があると「”host2″」だとか「’host3’」みたいに表示されてしまいますね。
これは事前に削除するなりダブルクォーテーション、シングルクォーテーションは使わない、というルールを決めれば良いのかも知れませんが、それはぼくの趣味じゃないのでマクロ側で吸収します。
先頭と末尾のダブルクォーテーション、シングルクォーテーション削除
これはstrtrimで解決できます。strtrimコマンドは指定した文字もしくは文字列を削除します。このコマンドを使ってダブルクォーテーション、シングルクォーテーションを削除するようにしています。
strtrimについて、今回は細かく解説しません。ダブルクォーテーション、シングルクォーテーションを削除するバージョンは次のようになります。
csvfile = "test.csv" separator = "," fileopen fh_csvfile csvfile 0 if fh_csvfile == -1 then messagebox 'csvファイルを開けません' 'エラー' endif while 1 ; ファイルから1行読む filereadln fh_csvfile csvbuf ; 最後まで読み込んだら終了 if result then break endif strsplit csvbuf separator 2 call csvtrim sprintf '[%s][%s]' groupmatchstr1 groupmatchstr2 messagebox inputstr csvbuf endwhile end :csvtrim s = "'" w = '"' for i 1 9 sprintf 'strtrim groupmatchstr%d %s' i '"'"' execcmnd inputstr sprintf 'strtrim groupmatchstr%d %s' i "'"'" execcmnd inputstr next return