[Powershell] iniファイルの情報の読み取りと書き込みまとめ


はじめに

Powershellにてiniファイルを取り扱う方法の備忘録です。

本記事では、iniファイルに記載されているKey=Value形式の情報の取得方法だけでなく、Key=Value情報の追加および編集についての方法もまとめておきます。

実行環境

環境

本検証を実施した環境は下記の通りである。

対象 内容
OS Windows 10 Pro 1909
Powershell 5.1.18362.1171

利用ファイル

本検証で利用したファイルは下記の通りである。

[test.ini]

; Test Ini File

; Test Section 1
[Section1]
BAR=AAAA
FOO=BBB

; Test Section 2

[Section2]
TEST=12345
FOO=CCC

iniファイルの読み込み

iniファイルの読み込み関数を作成します。

今回の読み込み方法は正規表現を利用して解析して情報を取得する方法となります。

基本的にセクションなしのiniファイル形式(key=value)で利用できるようにしています。

function GetIniContent($filePath) {

    $ini = [ordered]@{}
    $commentCount = 0

    switch -regex -file $filePath {
        "^\[(.+)\]" {
            $section = $matches[1]
            $ini[$section] = @{}
            $commentCount = 0
        }
        "^(;.*)$" {
            $value = $matches[1]
            $commentCount = $commentCount + 1
            $name = "Comment" + $commentCount
            if($section -eq $null) {
                $section = "NoSection"
                $ini[$section] = @{}
            }
            $ini[$section][$name] = $value
        }
        "(.+?)\s*=(.*)" {
            $name, $value = $matches[1..2]
            if($section -eq $null) {
                $section = "NoSection"
                $ini[$section] = @{}
            }
            $ini[$section][$name] = $value
        }
    }

    return $ini
}

$filePath = "C:\Work\test.ini"

# function呼び出し
$ini = GetIniContent $filePath
if ($ini -ne $null) {
    foreach ($sectionKey in $ini.Keys) {
        $sectionKey
        Write-Host "======================================="
        foreach ( $key in $ini[$sectionKey].Keys) {
            Write-Host $key `t`t $ini[$sectionKey][$key]
        }
        Write-Host
    }
}

上記の実行結果は下記の通りである。

NoSection
=======================================
BAR          ABC
Comment2     ; Test Section 1
Comment1     ; Test Ini File

Section1
=======================================
BAR          AAAA
FOO          BBB
Comment1     ; Test Section 2

Section2
=======================================
TEST         12345
FOO          CCC

iniファイルに記載したすべての情報がすべて取得できています。

セクションごとに同じキーを設定した場合でも別の情報として取得することができます。

もちろん下記のようにキーを指定して値を取得することもできます

$ini["Section1"]["BAR"]

# 出力結果
AAAA

取得したiniファイルのデータ配列に対してセクション名とキー名を指定してあげることで、その値を取得することができます。セクションがない場合は”NoSection"を指定するように上記は処理しています。

iniファイルの更新

では、iniファイルのKey=Valueデータの更新およびKey-Valueデータの新規追加を行います。


# まずは、iniデータ配列の変数を上書きします。 $ini["Section1"]["BAR"] = "ZZZZ" Write-Host $ini["Section1"]["BAR"] # 出力結果 ZZZZ

次にKey=Valueデータを「Section1」に追加します。

$ini["Section1"].Add("WOW", "DZDZDZ")
Write-Host $ini["Section1"]["WOW"]

# 出力結果
DZDZDZ

用意した配列データをファイルに書き出します。

# 元ファイルはバックアップしておく
Move-Item -Path $filePath -Destination "$filePath.bk" -Force

# 元ファイル名でファイルを新規作成
$outFile = New-Item -ItemType file -Path $filePath

foreach ($sectionKey in $ini.Keys | Sort-Object) {
    if($sectionKey -ne "NoSection") {
        Add-Content -Path $outFile -Value "[$sectionKey]"
    }

    foreach ($key in $ini[$sectionKey].Keys | Sort-Object ) {
        if($key -match "^Comment[\d]+") {
            Add-Content -Path $outFile -Value "$($ini[$sectionKey][$key])"
        } else {
            Add-Content -Path $outFile -Value "$key=$($ini[$sectionKey][$key])"
        }
    }
    Add-Content -Path $outFile -Value ""
}

上記を実行することで、iniファイルを再現することができました。(Sort-Objectを利用しているため、名前順に出力されます)

BAR=ABC
; Test Ini File
; Test Section 1

[Section1]
BAR=ZZZZ
; Test Section 2
FOO=BBB

[Section2]
FOO=CCC
TEST=12345


最後に

いかがでしたでしょうか。

Powershellでかつライブラリを利用しない場合は、結構面倒ですね。

Powershellにも「Psini」というパッケージがあり、こちらを利用すると結構楽にiniファイルを操作することができてしまいます。(下記参考)

PsIni 2.0.0 – PowerShell Gallery

こちらも是非使ってみてください。(時間があれば、こちらの使い方も紹介できればと思います)