【问题标题】:Calling dynamic variable in PowerShell在 PowerShell 中调用动态变量
【发布时间】:2017-08-04 15:11:38
【问题描述】:

我正在尝试创建一个新变量,该变量将使用具有动态名称的其他变量作为其值。这是我想要做的:

我有一个 System.Array 有两个值:

$Years = 2015, 2016

另一个变量$Transactions 有一个各种交易的列表。

我正在尝试通过以下方式使用每个 $Years 值:

foreach ($Year in $Years){
   New-Variable -Name "Transactions_$Year" -Value $Transactions |
     Where {$_.Date -like "*.$Year"}
}

现在我想做的(在同一个 foreach 循环中)是在创建另一个新变量时使用该 $Transactions_$Year 值,如下所示:

New-Variable -Name "Income_$Year" -Value $Transactions_$Year |
  Where {$_.Amount -NotLike "-*"} | 
    Measure-Object Amount -Sum | Select -ExpandProperty Sum

这可能吗,或者您有其他方法可以实现吗?

【问题讨论】:

    标签: powershell variables dynamic-variables indirection


    【解决方案1】:

    首先,您的 New-Variable 调用不会像您认为的那样做,因为您会将 New-Variable 的输出通过管道传输到 Where-Object 而不是使用 $Transactions | Where ... 的值作为多变的。你需要括号才能工作:

    New-Variable -Name "Transactions_$Year" -Value ($Transactions | Where {$_.Date -like "*.$Year" })
    

    如果你绝对必须使用这种方法,那么你可以通过Get-Variable再次获取变量:

    Get-Variable Transactions_$Year | % Value
    

    但是,具有魔术名称的多个变量是解决此问题的一种相当糟糕的方法。你可能更想要一张地图:

    $TransactionsPerYear = @{}
    $Years | ForEach-Object {
      $TransactionsPerYear[$_] = $Transactions | Where Date -like "*.$_"
    }
    

    您可以通过$TransactionsPerYear[2015] 获取 2015 年的所有交易。

    另一种方法是Group-Object,它甚至不需要列出可能的年份,而是按某些属性或表达式结果对多个对象进行分组:

    $TransactionsPerYear = $Transactions | Group-Object { [int]($_.Date -replace '.*\.') }
    

    (这是对它如何工作的猜测。您的日期字符串似乎包含一个句号,之后是年份,没有其他内容,所以可能类似于 dd.MM.yyyy 日期格式。

    【讨论】:

    • $TransactionsPerYear = @{} $Years | ForEach-Object { $TransactionsPerYear[$_] = $Transactions |其中 Date -like '*.$_' } 我没有得到任何东西,它不会创建变量 $TransactionsPerYear[2015] 或 $TransactionsPerYear[2016]。我也不太明白如何在第二阶段使用它,我想将每年的收入放入单独的变量中。
    • 那些不是变量,仅供参考。通过使用不同的名称来称呼事物,您只会使事情变得更加混乱。无论如何,我忘了在第二个例子中使用双引号,这就是为什么它不起作用。它现在应该可以工作了。 (或者在那个时候把引号去掉。)
    【解决方案2】:

    您想使用 Invoke-Expression cmdlet。您需要创建将使用该值初始化变量的命令的动态字符串表达式。以下是你的做法:

    $Years = 2015, 2016, 2017, 2018
    $Years | ForEach-Object { 
        $Year = $_
        Invoke-Expression ('$Year' + $Year + ' = "Year is ' + $Year + '"')
     }
    

    这是输出:

    Get-Variable Year*
    
    Name                           Value                                                                                                                                                                                                                             
    ----                           -----                                                                                                                                                                                                                             
    Year                           2018                                                                                                                                                                                                                              
    Year2015                       Year is 2015                                                                                                                                                                                                                      
    Year2016                       Year is 2016                                                                                                                                                                                                                      
    Year2017                       Year is 2017                                                                                                                                                                                                                      
    Year2018                       Year is 2018                                                                                                                                                                                                                      
    Years                          {2015, 2016, 2017, 2018}         
    

    【讨论】:

    • 我想说添加Invoke-Expression 只是在此处已经有问题的模式中添加另一个非常有问题的元素。不要这样做。 New-Variable 是一种非常好的创建变量的方法,而不会因需要正确转义要在 Invoke-Expression 中使用的东西而引起头痛。
    • 通过使用 Invoke-Expression,你可以做非常复杂和灵活的动态变量和值。不要认为这样做有什么不好。实现目标的另一种方式。
    • 这是 PowerShell 团队的观点:Invoke-Expression considered harmful
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 2013-03-05
    • 2012-05-27
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    相关资源
    最近更新 更多