LoginSignup
8
8

More than 3 years have passed since last update.

PowerShellで複数行のjsonファイルを読み込んでプロパティ数分ループする方法

Posted at

クラウド製品を利用しており、そのデータベース機能の定義ファイルをjson形式で生成する必要があり、地域 x テーブル種類数分の数百種類のjsonファイル生成を行ったメモ。

  1. 地域とテーブルの一覧をjsonで作成
  2. 一覧ファイルをPowerShellで読み込む
  3. 最低限必要な整形処理を施し出力

結合が行えない等の制約があるデータベースなため、奇妙なテーブル構成なことはスルー。

元となるjsonファイル

data.json
{
    "prefectures": [
        {
            "code": "Tokyo",
            "Name": "東京"
        },
        {
            "code": "Osaka",
            "Name": "大阪"
        },
        {
            "code": "Aichi",
            "Name": "愛知"
        },
        {
            "code": "Fukuoka",
            "Name": "福岡"
        }
    ],
    "tables": [
        {
            "code": "meeting_room",
            "name": "会議室",
            "field1": "id",
            "field2": "floar",
            "field3": "capacities"
        },
        {
            "code": "parking",
            "name": "駐車場",
            "field1": "id",
            "field2": "area",
            "field3": "space_number",
            "field4": "user_name",
            "field5": "car_number",
            "field6": "expire"
        }
    ]
}

以上のjsonファイルを元に生成したいjsonファイルは、
- Tokyo_metting_room.json
- Tokyo_parking.json
- Osaka_meeting_room.json
- Osaka_parking.json
- ...

複数行のjsonファイルを読み込む

jsonファイルはGet-Content -Path "filename.json"で読み込みが可能ですが、複数行にまたがるjsonファイルを読み込むには、引数に -Raw を追加する。

Get-Content -Path "filename.json" -Raw | ConvertFrom-Json

もし、-Rawをつけずに複数行のjsonファイルを読み込むと、エラーが表示される

Get-Content -Path "filename.json" | ConvertFrom-Json

ConvertFrom-Json : ':' または '}' ではなく無効なオブジェクトが渡されました。

読み込んだjsonファイルのカラムを取得

Get-Contentで読み込んだファイルはObject型、それをパイプでつなぎ、ConvertFrom-JsonでjsonファイルをPSCustomObject型に変換しています。

PSObjectのプロパティにアクセスすることで、Name値が取得できます。

# $objectはPSCustomObjectに変換された、jsonデータ
$object.psobject.Properties | ForEach-Object {
    return $_.Name
}

完成系

これらを組み合わた、最終的なソースコード

parse.ps1
<#
    Jsonデータから地域 x テーブル種類分のjsonを出力
#>
$file = "data.json" # 読み込む定義ファイル
$export = ".\results" # 出力ディレクトリ

# ファイルの存在確認
if (!(Test-Path -Path $file)) {
    exit
}

# 出力フォルダがなければ生成しておく
if (!(Test-Path -Path $export)) {
    New-Item -Path $export -ItemType Directory
}

# 定義ファイルを読み込む
# Get-Contentの引数に -Raw を入れることで複数行のjsonファイルを読み込む
Get-Content -Path $file -Encoding UTF8 -Raw | ConvertFrom-Json | ForEach-Object {
    $prefectures = $_.prefectures
    $tables = $_.tables

    # 地域数分ループする
    $prefectures | ForEach-Object {
        $pref_code = $_.code
        $pref_name = $_.name

        # $tables数分ループする
        $tables | ForEach-Object {
            $fields = $_
            # カラムの取得
            $columns = $fields.psobject.Properties | ForEach-Object {
                return $_.Name
            }
            $json = New-Object PSObject | Select-Object -Property $columns
            $table_name = $pref_code + "_" + $fields.code

            # カラムの数分ループする
            $columns | ForEach-Object {
                if ($_ -eq "code") {
                    $json.code = $pref_code + "_" + $fields.($_)
                } elseif ($_ -eq "name") {
                    $json.name = $pref_name + "_" + $fields.($_)
                } else {
                    $json.($_) = $fields.($_)
                }
            }

            # ファイル出力
            $export_directory = "${export}\${table_name}.json"
            $json | ConvertTo-Json | Out-File -FilePath $export_directory -Encoding utf8 -Force
        }
    }
}

生成結果

image.png
image.png
image.png

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8