はじめに
普段JavaScriptをよく書いているため、PowerShellにおいても以下のような書き方でオブジェクトのプロパティを文字列の中で展開しようとしたところエラーになった。
Write-Output "My name is ${profile.name}"
PowerShellにおける文字列内での変数の展開方法について、JavaScriptと対比しながら簡単にまとめる。
1. 変数を文字列の中で展開したい
本題に入る前に、まず基本的な展開方法について復習する。
①JavaScriptにおける変数の文字列内展開
文字列連結の基本は以下のように加算演算子(+)を用いたものであるが、
const target = 'world';
console.log('hello ' + target);
// 「hello world」と出力される
以下のように連結処理を行わず、文字列の中で変数を展開することもできる。
const target = 'world';
console.log(`hello ${target}`);
// 「hello world」と出力される
JavaScriptで文字列内で変数を展開する場合は、バッククォート(`)を使用し、展開したい変数はダラー($)を先頭につけて変数名を中括弧({})で囲む。
②PowerShellにおける変数の文字列内展開
PowerShellにおいても、文字列の連結や変数の展開がJavaScriptと同じように行える。
加算演算子を使う場合
$target = 'world'
Write-Output('hello ' + $target)
# 「hello world」と出力される
文字列内で変数を展開する場合
PowerShellの場合はバッククォート(`)ではなくダブルクォーテーション(")なので注意。
$target = 'world'
Write-Output("hello ${target}")
# 「hello world」と出力される
文字列内変数展開のアンチパターン
以下のように中括弧({})を使用せずに変数展開を行うこともできるが、
$item = 'apple'
Write-Output("i have an $item")
# 「i have an apple」と出力される
スペース等が無い文字列を作成する場合、失敗するためオススメできない。
$item = 'apple'
Write-Output("i have $items")
# 変数$itemsと解釈されるため「i have 」と出力されてしまう
Write-Output("i have ${item}s")
# これなら「i have apples」と出力される
2. オブジェクトのプロパティを文字列の中で展開したい
本題。
①JavaScriptにおけるオブジェクトのプロパティの文字列内展開
プロパティ名まで含めて中括弧で囲めば良い。
const profile = {
name: 'ako',
like: 'basketball'
};
console.log(`my name is ${profile.name}`);
// 「my name is ako」と出力される
②PowerShellにおける変数の文字列内展開
プロパティ名まで中括弧で囲んでも できない。
$profile = @{
name = 'ako';
like = 'basketball';
}
Write-Output("my name is ${profile.name}")
# 変数$profile.nameと解釈されるため(?)「my name is 」と出力されてしまう
オブジェクトのプロパティを文字列内で展開する場合は括弧(())を使う。
$profile = @{
name = 'ako';
like = 'basketball';
}
Write-Output("my name is $($profile.name)")
# 「my name is ako」と出力される
ちなみに、コマンドの実行結果をそのまま文字列内で展開したい時もこの方法を使う。
$message = "Date: $(Get-Date)"
つまるところ、$()
で一旦コマンド実行されていると解釈するのがよさそう。
おわりに
私は中括弧での展開ができなかった時に「PowerShellはオブジェクトのプロパティを文字列内で展開する方法はないんだ!」と勘違いして加算演算子を使ってました。
言語によって細かい記法が異なるからあまり思い込みで感覚的に使わない方がよさそうだと反省しました。
にしても変数とプロパティで展開方法が異なるのは規則的によくわからんし公式ドキュメントも色んな用法が散らばってるしPowerShellホントきらい