いいタイトルが思いつかなくてごめんなさい。
経緯
ちょっとお仕事でこんなシェル*1を作ることになりまして、
#!/bin/sh sqlplus test/test@orcl << EOF select * from aaaa where id = ${id} and name = ${name} ; EOF
作る部分は << EOF から EOF の間のSQLなんですが、そのままシェルの中に書いてたらSQLを実行させながら作れないですよね。というわけで、ちょっと遊んでみました。
ちょこっとやってみた
そうだ、PowerShellで遊んでみよう!もちろん、業務時間に?
というわけで、以下のようなファイルを同一ディレクトリ内に用意します。
テンプレート(test.tpl)
シェルのひな形です。
#INSERT
#!/bin/sh sqlplus test/test@orcl << EOF #INSERT<test_01.sql> EOF
SQLファイル(test_01.sql)
メインのロジック部分。
「/*
select * from hoge where id = /*<REPLACE ${id} */ 999 /*>*/ and name = /*<REPLACE ${name} */ 'nakaji' /*>*/ ;
PowerShellスクリプト(test.ps1)
以下の内容でスクリプトを作成しました。エラー処理はざるです。
引数にテンプレートファイルを指定して実行すると、標準出力に結果が出力されるのでリダイレクトするなりしてファイルに保存します。
Param([String]$templateName)
function InsertFile([String]$directory, [String]$fileName)
{
$insertFileName = Join-Path $directory $fileName
if (-not(Test-Path $insertFileName)) {
Write-Error ("ファイルが存在しません:" + $insertFileName)
return;
}
Get-Content $insertFileName
}
Get-Content $templateName |
%{
# 「#<INSERT hoge>」の部分を「hoge」のファイルの内容に差し替える
if ($_ -match "^#INSERT<(.+)>.*") {
#Split-Path $templateName -Parent | InsertFile($_, $matches[1])
$directory = Split-Path $templateName -Parent
$buf = InsertFile $directory $matches[1]
$buf
} else {
$_
}
} | %{
# 「/*<REPLACE hoge */ piyo /*>*/」 を 「hoge」に置換
$_ -replace '/\*<REPLACE\s+(.+)\s+\*/\s.+\s/\*>\*/', '$1'
}
実行
PS D:\> .\test.ps1 .\test.tpl
#!/bin/sh
sqlplus test/test@orcl << EOF
select * from aaaa
where id = ${id}
and name = ${name}
;
EOFよっしゃこれでちょっと楽ができる!と思ったら、その前にそのお仕事は終わってましたとさ。orz
*1:実際はもうちょっと複雑なんだよ!本当だよ!