繁体   English   中英

PowerShell:在字符串中使用未声明的变量

[英]PowerShell: Use undeclared variable in string

我试图弄清楚如何在字符串中使用未声明的变量。 这是一个演示我的问题的简化示例

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

$age = 3
$sentence | write-output

寻找这个 output:

   My dog is 6 years old

   My dog is 3 years old

获取此 output:

   My dog is  years old

   My dog is  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 $age years old") #My dog is 3 years old

有没有可能以任何方式使它更紧凑? 还是这是唯一的方法?


编辑:我注意到重点是字符串。 我将在出现问题的地方分享我的代码。 我需要迁移一堆 VBS 脚本(> 40)从 20 行到 2000 行到 Powershell

VBS 文件:

    Function InitializeApp

        Dim sPath
        
        ...

    End function 

Powershell 脚本:

$vbs=Get-Content -path $path #get content in array, one line per index
$rules=
@(
    [pscustomobject]@{
        "name"="func_start";
        "vbs" = 'Function (?<V1>\w*)'; # The regex named group V1 will initialized when match is found
        "ps" = {"Function $1() `{`n"} # Group V1 is to be inserted in replacement string
    }
)

function Invoke-TestAndReplace($line,$ruleName){
    $r_vbs=$($rules.where({$_.name -eq $ruleName}).vbs) # Function (?<V1>\w*)
    $r_ps=$($rules.where({$_.name -eq $ruleName}).ps) # {"Function $1() `{`n"}
    if( $regex = ($line | select-string -pattern $r_vbs )) {
        $0=$regex[0].Matches.Groups.Where({$_.name -eq "0"}).value # Function InitializeApp
        $1=$regex[0].Matches.Groups.Where({$_.name -eq "V1"}).value # InitializeApp
        $2=$regex[0].Matches.Groups.Where({$_.name -eq "V2"}).value #
        $r_ps = & $r_ps # Function InitializeApp() {
        $replace = $line.replace($0,$r_ps) # Function InitializeApp -> Function InitializeApp() {
    } else {$replace = $line} #keep old value
    return $replace
}
$newVBS=@()
foreach($line in $vbs){
    $line = Invoke-TestAndReplace -line $line -rulename "func_start"
}

我不知道如何使用插值来做到这一点,但我可以使用 older.Net String.Format()方法来做到这一点,如下所示:

$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

我们可以这样缩短(感谢评论者):

$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

还要注意模板字符串中的不同占位符。

这个答案显示了一个过于复杂的替代方案,而不是 Joel Coehoorn 的好答案 您可以使用Script Block来存储表达式(包括您的$age变量)然后执行它。

$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

如果您希望您的脚本块在创建变量时“记住”变量的值,您可以使用它的.GetNewClosure()方法,例如:

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

您可以使用扩展字符串

$sentence = 'My dog is $age years old.'

$age = 4
$ExecutionContext.InvokeCommand.ExpandString($sentence)
# My dog is 4 years old.

$age = 5
$ExecutionContext.InvokeCommand.ExpandString($sentence)
# My dog is 5 years old.

您还可以定义一个 function 并调用 function

function sentence([int]$age) {
    "My dog is $age years old"
}

1..5 | ForEach-Object { sentence -age $_ }

# My dog is 1 years old
# My dog is 2 years old
# My dog is 3 years old
# My dog is 4 years old
# My dog is 5 years old

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM