2019年3月17日日曜日

PowerShellで、たとえば設定ファイルの内容を変更して保存したい時の簡単なやり方 (連想配列を使うよ)

設定ファイルの内容を変更して保存したい・・・こういうケースはとても多いと思います。

プログラムを組んで処理すればどうにでもなりますが、状況によっては、PowerShellを使うと数行くらいで簡単に済ませる事も可能なので、今回はそれをやってみたいと思います。


■設定ファイルのテンプレートを用意

やり方は千差万別ありますが、まずは話を簡単にするため、ここでは以下の仕様でやってみたいと思います。

  • 設定ファイルはUTF-8(BOMなし)テキスト
  • 設定ファイルの元になるテンプレートを用意
  • テンプレートの内容をリプレース
  • リプレース後のテンプレートで設定ファイル更新
■設定ファイルの内容



<?xml version="1.0" ?>
<setting>
    <machineid>{0}</machineid>
    <macineid2>{0}</machineid2>
    <machinespeed>{1}</machinespeed>
    <machinelocation>{2}</machinelocation>
</setting>

↑こんな感じでテンプレート(C:¥TEMP¥MY_SETTING_TEMPLATE.xml)を用意します。

ここの{0}※2箇所あります、{1}、{2}を必要なパラメータ値にリプレース(設定)してあげるわけです。


■PowerShellコマンドは6ステップだけ



#(1)テンプレートのパス指定
$PATH1="C:\TEMP\MY_SETTING_TEMPLATE.xml"

#(2)結果ファイルのパス指定
$PATH2="C:\TEMP\MY_SETTING.xml"

#(3)テンプレートの読込
$F1=GET-CONTENT $PATH1

#(4)リプレースしたいパラメータと値を定義
$PARAMS=@{"{0}"="00123"; "{1}"="M001"; "{2}"="010538"} 

#(5)テンプレートの内容をリプレース
foreach($P in $PARAMS.Keys){$F1=($F1.replace($P,$PARAMS[$P]));}

#(6)結果をファイル出力(BOMなしUTF-8)
$ENC=NEW-OBJECT System.Text.UTF8Encoding -ArgumentList @($false)
[System.IO.File]::WriteAllLines($PATH2,$F1,$ENC)

#結果表示
GET-CONTENT $PATH2



↑PowerShellは、たったの6ステップ (7行)だけです。

BOMなしUTF-8でファイルを出力するため少し込み入った記述をしていますが、BOMありで良ければ、単純にOUT-FILEコマンドレット一発でも良いためさらにシンプルに出来ます。

ただ、リプレースしたいパラメータは、連想配列(ハッシュテーブル)として直書きしているので、ここをどうするか?で手間は増減しそうです。

PowerShellは、文法は独特のものがありますが、あくまでもプログラミング言語のC#がベースになっているため、DOSのように過度な記号化を受けたり、逆に難しくなる省略表記を受けたりしないので、流れが掴みやすく分かりやすいと思います。




<setting>
    <machineid>00123</machineid>
    <macineid2>00123</machineid2>
    <machinespeed>M001</machinespeed>
    <machinelocation>010538</machinelocation>
</setting>


↑GET-CONTENTコマンドレットで設定ファイルの中身を読むと、パラメータがちゃんと設定されているのが分かります。

ちなみに設定ファイルを書き換える時は、ケースバイケースですが、実体に直接更新をかけないでテンプレートを用意して毎回リプレースが良い気がします。

実体を間違って破壊されても、毎回復元が可能だからです。