Вызов динамической переменной в PowerShell

Я пытаюсь создать новую переменную, которая будет использовать в качестве значения другую переменную с динамическим именем. Вот что я пытаюсь сделать:

У меня есть 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

}

Возможно ли это, или у вас есть какие-либо альтернативные способы, как я мог бы добиться этого?


person Community    schedule 14.03.2017    source источник


Ответы (2)


Прежде всего, ваш вызов 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 "*.$_"
}

И вы можете получить все транзакции за 2015 год с помощью $TransactionsPerYear[2015].

Другим способом является Group-Object, который даже не требует для начала списка возможных лет, но группирует ряд объектов по некоторому свойству или результату выражения:

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

(Это предположение о том, как это может работать. Похоже, ваша строка даты содержит что-то до точки, после которой идет год и ничего больше, поэтому, возможно, что-то вроде формата даты dd.MM.yyyy.

person Joey    schedule 14.03.2017
comment
$TransactionsPerYear = @{} $Years | ForEach-Object { $TransactionsPerYear[$_] = $Transactions | Где Date -like '*.$_' } Я ничего не получил, он не создает переменные $TransactionsPerYear[2015] или $TransactionsPerYear[2016]. Я также не совсем понял, как я могу использовать это на втором этапе, где я хочу получить доход за каждый год в отдельную переменную. - person ; 14.03.2017
comment
Это не переменные, просто к вашему сведению. Вы только еще больше запутываете ситуацию, называя вещи разными именами. В любом случае, я забыл использовать двойные кавычки для второго примера, поэтому это не сработало. Теперь это должно работать. (Или просто оставьте кавычки в этом месте.) - person Joey; 14.03.2017

Вы хотите использовать командлет Invoke-Expression. Вам необходимо создать динамическое строковое выражение команд, которое бы инициализировало переменную со значением. Вот как это сделать:

$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}         
person Kirill Pashkov    schedule 14.03.2017
comment
Я бы сказал, что добавление Invoke-Expression просто добавляет еще один очень сомнительный элемент к уже сомнительному шаблону. Не делай этого. New-Variable — это прекрасный способ создать переменную, не вызывая головной боли, связанной с необходимостью правильного экранирования вещей для использования в Invoke-Expression. - person Joey; 14.03.2017
comment
Используя Invoke-Expression, вы можете создавать действительно сложные и гибкие динамические переменные и значения. Не вижу в этом ничего плохого. Еще один способ достижения цели. - person Kirill Pashkov; 14.03.2017
comment
Вот точка зрения команды PowerShell: Invoke-Expression считается вредным - person mklement0; 19.11.2018