Powershell で JSON から読み込んだオブジェクトにピリオド(ドット)入りのキー名があり、これにどうやってアクセスしようか悩みました。
{
"user": {
"user.name": "testuser",
"user.email": "[email protected]"
}
}
例えばこんな config.json
があるとします。
この JSONファイル を読み込み、ユーザの入力を受け付けて設定を上書きするスクリプトを書きました。
# JSONファイル 読み込み
[String]$configPath = Join-Path ( Convert-Path . ) 'config.json'
$configData = Get-Content -Path $configPath -Raw -Encoding UTF8 | ConvertFrom-JSON
# 一度出力
Write-Host $configData.user['user.name']
# 入力受付
[String]$username = Read-Host 'ユーザー名 を入力してください (半角英数字と一部記号 (-, _) )。'
if (-not ($username -match "^[a-zA-z0-9\-_]+$") ) {
Write-Host 'ERROR: ユーザ名 に使用できない文字が含まれています。' -BackgroundColor DarkRed
Write-Host `r`n
exit
}
$configData.user['user.name'] = $username
# 再度出力
Write-Host $configData.user['user.name']
ここで問題となったのが user.name
という .
(ピリオド(ドット))入りのキー名。オブジェクトで .
でキー名を連結できるのが JavaScript に似ていたので、つい JavaScript のように $configData.user['user.name']
と書いてしましました。
すると
> PowerShell -ExecutionPolicy RemoteSigned .\test.ps1
ユーザー名 を入力してください (半角英数字と一部記号 (-, _) )。: aaa
型 System.Management.Automation.PSObject のオブジェクトにインデックスを付けることはできません。
発生場所 PATH\TO\PROJECT\test.ps1:16 文字:1
+ $configData.user['user.name'] = $username
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) []、RuntimeException
+ FullyQualifiedErrorId : CannotIndex
怒られました。しかも、初出の位置ではなく変数で上書きする部分で。初出の Write-Host
による標準出力はブランクを出力してスルーされたようです。
以上より、
となるようです。困った。
プロパティ名に文字列を使用しても、やはり機能します。
$myObject.'Name'
なん……だと……。
ということで上記スクリプトを書き換えます。
# JSONファイル 読み込み
[String]$configPath = Join-Path ( Convert-Path . ) 'config.json'
$configData = Get-Content -Path $configPath -Raw -Encoding UTF8 | ConvertFrom-JSON
# 一度出力
Write-Host $configData.user.'user.name'
# 入力受付
[String]$username = Read-Host 'ユーザー名 を入力してください (半角英数字と一部記号 (-, _) )。'
if (-not ($username -match "^[a-zA-z0-9\-_]+$") ) {
Write-Host 'ERROR: ユーザ名 に使用できない文字が含まれています。' -BackgroundColor DarkRed
Write-Host `r`n
exit
}
$configData.user.'user.name' = $username
# 再度出力
Write-Host $configData.user.'user.name'
肝は $configData.user.'user.name'
。 $configData.user['user.name']
の角括弧 ([]
)を外してキー名の文字列をそのまま .
(ピリオド(ドット)) で繋げました。
> PowerShell -ExecutionPolicy RemoteSigned .\test.ps1
testuser
ユーザー名 を入力してください (半角英数字と一部記号 (-, _) )。: abc
abc
上手く行きました。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント