2019/08/12(月)CSV を strdim 形式の外部ファイルに変換するマクロ

2021/05/21 07:09 Macro::macro サンプル

CSV を strdim 形式の外部ファイルに変換するマクロ

このサンプルマクロは、以下の仕様を満たすものとします。

マクロの目的

アイデアとしては、文字列型配列を CSV 形式で記述したくてマクロを起こしました。

次の意味を持つ各フィールドで区切られた CSV ファイルを strdim で定義された外部ファイルへ変換します。
フィールドの意味入力内容
1列目Environment環境
2列目Protocolアクセスプロトコル
3列目hostnameホスト名
4列目IPaddrIPアドレス
5列目Portポート番号
6列目Usernameアクセスユーザ名
7列目etc備考

また、データの入出力用ディレクトリを、以下のように定義します。
ディレクトリ意味
dat入出力ファイルを格納します。
tmp一時ファイルを出力します。
マクロファイルを置いたディレクトリからの相対パスで指定していることに注意してください。


生成したデータファイルは、別途 include で読み込んで利用する想定です。
include を利用したマクロ利用は 文字列型配列を別ファイルへ外出しする を参照してください。

利用可能環境

Teraterm
依存する Tera Term バージョン:Tera Term 4.77 以降*1

利用する Tera Term コマンド:
種別:制御Ver機能の簡易説明
break4.53以降ループから抜ける。
callサブルーチンをコールする。
continue4.77以降ループの次の反復処理に移る。
endマクロの実行そのものを終了する。
if,then,elseif,else,endif条件分岐
returnサブルーチンを抜け、メインルーチンへ戻る。
while,endwhile繰り返す。
種別:文字列操作Ver機能の簡易説明
sprintf4.52以降フォーマットされた出力を返す。
strscan部分文字列の位置を返す。
strsplit4.67以降文字列を分割する。
種別:ファイル操作Ver機能の簡易説明
filecloseファイルハンドルを閉じる。
filecreateファイルを作成する。
fileopenファイルを開く。
filereadlnファイルから一行読む。
filesearchファイルまたはフォルダがあるか確かめる。
filewritelnファイルに文字列を改行付きで書き込む。
foldersearch4.69以降フォルダがあるか確かめる。
makepathフルパス名を作成する。
種別:その他Ver機能の簡易説明
messageboxダイアログボックスを開き、ユーザーにメッセージを知らせる。
4.54以降特殊文字の解釈を制御するオプションの追加。
4.60以降キャンセル時にマクロ停止を確認する機能の追加。

マクロの使い方

実行タイミング
任意のタイミングで実行可能です。
マクロの指定方法
詳細は TeraTerm マクロの使い方 を参照してください。
ttpmacro.exe を利用する場合
ファイルの拡張子 .ttl を ttpmacro.exe へ関連付けしておきます。
.ttl ファイルをダブルクリック等で実行します。
ttermpro.exe を利用する場合
ttermpro.exe を利用する場合は、起動時にオプションへ /M=xxx.ttl のように指定します。
メニューから実行する場合
Tera Term メニューから「コントロール(O)」→「マクロ(M)」を選択します。
対象ファイルを選択して「開く」ボタンをクリックすると、実行されます。

*1 : 保存する文字コードによっては Tera Term バージョン 4.102 以降

コード

著作権情報

このサンプルマクロに関する著作権は、当サイト管理者が所有しています。
著作権者
神場 和也
ライセンス
3条項BSDライセンス
関連情報
(なし)

サンプルコード

ファイルダウンロード
csvconv.zip

※ 解凍してご利用ください。
項目内容
文字コードShift JIS
実行確認バージョンTera Term Ver 4.103
備考下記コピペ用ソースコードをファイルに保存したものです。
想定するフォルダ構成
デフォルトでは、以下の構成で利用することを想定しています。
必要に応じて、適切に修正してください。
csvconv.ttl
├─ dat/
└─ tmp/
コピペ用
以下のソースコードをファイルに保存のうえご利用ください。

※ UTF-8 で保存した場合は、Tera Term Ver 4.102 以降で実行する必要があります。詳細は マクロファイルの仕様 を参照してください。

・CSV ファイルサンプル
想定ファイル名:example.csv
#1_Environment,2_Protocol,3_hostname,4_IPaddr,5_Port,6_Username,7_etc
本番,ssh2,serv01,192.168.0.1,22,root,sample
本番,rdp,win01,192.168.0.2,3389,administrator,
開発,telnet,switch01,192.168.0.3,23,admin,
CSV の文字コードは Shift JIS である必要があります。
(UTF-8 で CSV を作成した場合、日本語が文字化けする可能性があります)

・CSV を strdim 形式の外部ファイルに変換するマクロ
想定ファイル名:csvconv.ttl
; CSV を strdim 形式の外部ファイルに変換するマクロ

; File: csvconv.ttl
; Description: CSV を strdim 形式の外部ファイルに変換するマクロ
; Environment: generic
; Update: 2019/8/12
; Author: Kazuya Jimba

;;; 環境設定 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

comma = ','

_line_count = 0
_tmp_count  = 0

; ディレクトリ
_output_dir = 'dat'
_tmp_dir = 'tmp'

; ファイル
_src_file  = 'example.csv'
_dest_file = 'csvconvert.dat'

_field_name_1 = '_Environment'
_field_name_2 = '_Protocol'
_field_name_3 = '_hostname'
_field_name_4 = '_IPaddr'
_field_name_5 = '_Port'
_field_name_6 = '_Username'
_field_name_7 = '_etc'

_output_field_1 = 'field1.dat'	; 1_Environment
_output_field_2 = 'field2.dat'	; 2_Protocol
_output_field_3 = 'field3.dat'	; 3_hostname
_output_field_4 = 'field4.dat'	; 4_IPaddr
_output_field_5 = 'field5.dat'	; 5_Port
_output_field_6 = 'field6.dat'	; 6_Username
_output_field_7 = 'field7.dat'	; 7_etc

; パス
makepath _src_path _output_dir _src_file
makepath _dst_path _output_dir _dest_file

makepath _tmp_f1_path _tmp_dir    _output_field_1
makepath _tmp_f2_path _tmp_dir    _output_field_2
makepath _tmp_f3_path _tmp_dir    _output_field_3
makepath _tmp_f4_path _tmp_dir    _output_field_4
makepath _tmp_f5_path _tmp_dir    _output_field_5
makepath _tmp_f6_path _tmp_dir    _output_field_6
makepath _tmp_f7_path _tmp_dir    _output_field_7

;;; メイン処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; 出力先の存在確認
targetname = _output_dir
call fnChkFile
if result != 1 then
  sprintf "Not exist directory. (%s)" _output_dir
  messagebox inputstr 'Error'
  end
endif

targetname = _tmp_dir
call fnChkFile
if result != 1 then
  sprintf "Not exist directory. (%s)" _tmp_dir
  messagebox inputstr 'Error'
  end
endif

; ファイルの存在確認
targetname = _src_path
call fnChkFile

; 存在する場合のみ実行
if result == 0 then
  sprintf "%s が存在しません。" _src_path
  messagebox inputstr 'Error'
  end

elseif result == 2 then
  ; テンポラリファイルオープン
  filecreate destfile1 _tmp_f1_path
  filecreate destfile2 _tmp_f2_path
  filecreate destfile3 _tmp_f3_path
  filecreate destfile4 _tmp_f4_path
  filecreate destfile5 _tmp_f5_path
  filecreate destfile6 _tmp_f6_path
  filecreate destfile7 _tmp_f7_path

  fileopen srcfile _src_path 0
  while 1
    ; 一行読み込み
    filereadln srcfile workline
    if result == 1 then 
          break
    endif

    ; コメント行なら無視
    strscan workline '#'
    if result > 0 then
      continue
    endif

    ; 読み込んだ行をフィールドごとにテンポラリ生成
    strsplit workline comma

    filewriteln destfile1 groupmatchstr1
    filewriteln destfile2 groupmatchstr2
    filewriteln destfile3 groupmatchstr3
    filewriteln destfile4 groupmatchstr4
    filewriteln destfile5 groupmatchstr5
    filewriteln destfile6 groupmatchstr6
    filewriteln destfile7 groupmatchstr7

    ; 生成した行をカウント
    _line_count = _line_count + 1

    ; ファイル最後まで繰り返す
  endwhile

  ; テンポラリファイルクローズ
  fileclose destfile1
  fileclose destfile2
  fileclose destfile3
  fileclose destfile4
  fileclose destfile5
  fileclose destfile6
  fileclose destfile7

  ; ファイルクローズ
  fileclose srcfile

  ; 変換データ生成
  filecreate destpath _dst_path

  ; フィールド 1
  _field_name = _field_name_1
  _destfile   = destfile1
  _tmp_f_path = _tmp_f1_path
  call DestFileWriteln

  ; フィールド 2
  _field_name = _field_name_2
  _destfile   = destfile2
  _tmp_f_path = _tmp_f2_path
  call DestFileWriteln

  ; フィールド 3
  _field_name = _field_name_3
  _destfile   = destfile3
  _tmp_f_path = _tmp_f3_path
  call DestFileWriteln

  ; フィールド 4
  _field_name = _field_name_4
  _destfile   = destfile4
  _tmp_f_path = _tmp_f4_path
  call DestFileWriteln

  ; フィールド 5
  _field_name = _field_name_5
  _destfile   = destfile5
  _tmp_f_path = _tmp_f5_path
  call DestFileWriteln

  ; フィールド 6
  _field_name = _field_name_6
  _destfile   = destfile6
  _tmp_f_path = _tmp_f6_path
  call DestFileWriteln

  ; フィールド 7
  _field_name = _field_name_7
  _destfile   = destfile7
  _tmp_f_path = _tmp_f7_path
  call DestFileWriteln

  fileclose destpath

endif


;;; 終了処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

end

;;; サブルーチン ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

:fnChkFile
; #################################
; 変数 targetname 内の文字列がファイルかフォルダかを判定するサブルーチン
; result
; 0 = 対象は存在しなかった。
; 1 = 対象はフォルダだった。
; 2 = 対象はファイルだった。
; #################################

filesearch targetname
if result = 1 then
    ; 対象が存在する場合

    ; フォルダであるか確認する
    foldersearch targetname 
    if result = 1 then
        ; フォルダの場合 (存在する対象がフォルダである)
        result = 1

    else
        ; ファイルの場合 (存在するがフォルダではない)
        result = 2
    endif

else
    ; 対象が存在しない場合
    result = 0

endif

return

:DestFileWriteln
; #################################
; フィールドごとに出力ファイルへ書き出すサブルーチン
; 呼び出す前に、以下の変数を定義する必要がある
;  _field_name = _field_name_X
;  _destfile   = destfileX
;  _tmp_f_path = _tmp_fX_path
; #################################

sprintf "strdim %s %d" _field_name _line_count
filewriteln destpath inputstr

fileopen _destfile _tmp_f_path 0
_tmp_count = 0

while 1
  ; 一行読み込み
  filereadln _destfile workline
  if result == 1 then
        break
  endif

  sprintf "%s[%d] = '%s'" _field_name _tmp_count workline
  filewriteln destpath inputstr

  _tmp_count = _tmp_count + 1

endwhile
fileclose _destfile
filewriteln destpath ''

return

備考

特にありません。