Home > OS >  PowerShell: Use undeclared variable in string
PowerShell: Use undeclared variable in string

Time:04-24

I'm trying to figure out how I can use undeclared variables in a string. This is a simplified example to demonstrate my issue

[string]$sentence="My dog is $age years old"
[int]$age = 6 
$sentence | write-output

$age = 3
$sentence | write-output

Looking for this output:

   My dog is 6 years old

   My dog is 3 years old

Getting this output:

   My dog is  years old

   My dog is  years old

I've tried the following:

  "My dog is `$age years old" #My dog is $age years old
  $("My dog is `$age years old") #My dog is $age years old
  $("My dog is $age years old") #My dog is 3 years old

Is it possible in any way to make this more compact? or is this the only way?

CodePudding user response:

I don't know how to do this with interpolation, but I can do it with the older .Net String.Format() method like this:

$sentence = "My dog is {0} years old."

$age = 6
[string]::Format($sentence, $age) | Write-Output
# => My dog is 6 years old

$age = 3
[string]::Format($sentence, $age) | Write-Output
# => My dog is 3 years old

[string]::Format($sentence, 12)   | Write-Output
# => My dog is 12 years old

Which we can shorten like this (thank you commenters):

$sentence = "My dog is {0} years old."

$age = 6
Write-Output ($sentence -f $age)
# => My dog is 6 years old

$age = 3
Write-Output ($sentence -f $age)
# => My dog is 3 years old

Write-Output ($sentence -f 12)
# => My dog is 12 years old

Also note the different placeholder in the template string.

CodePudding user response:

This answer shows an overcomplicated alternative to the nice answer from Joel Coehoorn. You can use a Script Block, to store an expression (including your $age variable) and then execute it.

$sentence = { "My dog is $age years old" }
$age = 6 
& $sentence | write-output # => My dog is 6 years old

$age = 3
& $sentence | write-output # => My dog is 3 years old

If you want your script block to "remember" the value of a variable at the moment it was created you can use it's .GetNewClosure() method, for example:

$expressions = foreach($i in 0..5) {
    { "Value of `$i was $i in this iteration" }.GetNewClosure()
}
$expressions.foreach{ & $_ }
  • Related