Объявить здесь-строку, содержащую переменные вне цикла

Я хотел бы объявить здесь-строку вне цикла, используя эту строку в цикле, где разрешаются переменные.

Мой идеальный сценарий будет выглядеть следующим образом. Это не работает, так как Powershell оценивает строку один раз перед входом в цикл, а не каждый раз внутри цикла.

$number = "Number $($_)"
1..2 | % { $number }

Я знаю, что могу использовать одно из этих решений

1..2 | % { "Number $($_)" }

$number = "Number {0}"
1..2 | % { $number -f $_ }

$number = "Number <replace>"
1..2 | % { $number -replace "<replace>", "$_" }

но у них есть недостатки, которых я хотел бы избежать

  • Из-за размера строки объявление ее внутри цикла запутывает логику цикла, делая код менее читаемым.

  • Решение форматирования слишком легко ошибиться, когда задействовано много переменных.

  • В решении замены проще сопоставить, что заменяется какой переменной, но мне пришлось бы связать много команд replace.

Изменить

Перечитывая мой собственный вопрос, становится очевидным, что фактический вариант использования отсутствует в вопросе.
Обратите внимание, что в конечном итоге я выбрал вариант форматирования

Ниже будет объявлен шаблон с некоторыми переменными, которые необходимо заменить в цикле.

    $sqltemplate = @"
        SELECT  aud.dpt_mov_hex||aud.dpt_ref||aud.can_typ||TO_CHAR(aud.dte_aud-1,'YYYYMMDD')||'000001' transaction_id,
                acc.dos_nbr contract_id, acc.pay_acc_nbr account_id, 
                CASE WHEN NULL IS NULL THEN unt.nam_unt ELSE unt.nam_unt||'<'||NULL ||'>' END product_id,
                aud.dpt_ref, aud.dpt_mov_hex, aud.dpt_mov_dte uitwerkingsdatum, 
                CASE WHEN can_typ = 0 THEN 'VZ'||aud.dpt_mov_ven_typ ELSE 'VZ'||aud.dpt_mov_ven_typ||'-CR' END transactietype,
                aud.dpt_mov_amt_eur bedrag_in_eur, aud.dte_cnv, aud.dpt_mov_fix_eur, aud.dpt_mov_con_inc, aud.dpt_mov_amt_sgn bedrag_teken,
                aud.dpt_mov_amt_unt bedrag_in_units, aud.dpt_mov_amt_rte, aud.dpt_mov_amt_val_pre, aud.dpt_mov_amt_val_aft,
                aud.dpt_mov_amt_ioc, aud.dte_exe verwerkingsdatum, aud.exe_mng, aud.cmt, aud.trn_nbr, aud.dte_aud datum_aanlevering, aud.can_typ
        FROM    lfe_dpt_mov_aud aud, vnv_isr_pay_acc acc, vnv_bel_unt unt
        WHERE   aud.dte_aud >= TO_DATE('$((Get-Date).ToString('dd.MM.yyyy'))', 'DD.MM.YYYY')
                AND aud.dpt_ref = '{0}'
                AND acc.pay_acc_nbr = '{1}'
                AND unt.inv_unt = '{2}'
        UNION
        SELECT  aud.dpt_mov_hex||aud.dpt_ref||aud.can_typ||TO_CHAR(aud.dte_aud-1,'YYYYMMDD')||'000001' transaction_id,
                acc.dos_nbr contract_id, acc.pay_acc_nbr account_id, 
                CASE WHEN itr_rte IS NULL THEN unt.nam_unt ELSE unt.nam_unt||'<'||itr_rte ||'>' END product_id,
                aud.dpt_ref, aud.dpt_mov_hex, aud.dpt_mov_dte uitwerkingsdatum,
                CASE WHEN can_typ = 0 THEN 'VZ'||aud.dpt_mov_ven_typ ELSE 'VZ'||aud.dpt_mov_ven_typ||'-CR' END transactietype, 
                aud.dpt_mov_amt_eur bedrag_in_eur, aud.dte_cnv, aud.dpt_mov_fix_eur, aud.dpt_mov_con_inc, aud.dpt_mov_amt_sgn bedrag_teken,
                aud.dpt_mov_amt_unt bedrag_in_units, aud.dpt_mov_amt_rte, aud.dpt_mov_amt_val_pre, aud.dpt_mov_amt_val_aft,
                aud.dpt_mov_amt_ioc, aud.dte_exe verwerkingsdatum, aud.exe_mng, aud.cmt, aud.trn_nbr, aud.dte_aud datum_aanlevering, aud.can_typ
        FROM    lfe_dpt_mov_aud aud, vnv_dpt dpt, vnv_isr_pay_acc acc, vnv_bel_unt unt
        WHERE   aud.dpt_ref = dpt.dpt_ref
                AND dpt.pay_acc = acc.pay_acc_nbr
                AND dpt.inv_unt = unt.inv_unt
                AND aud.dte_aud >= TO_DATE('$((Get-Date).ToString('dd.MM.yyyy'))', 'DD.MM.YYYY')
                AND acc.pay_acc_nbr = '{1}'
                AND unt.inv_unt = '{2}'
        UNION
"@

и этот шаблон будет использоваться в заявлении, подобном этому

$rolledbackMatchs — это массив настраиваемых объектов, содержащий три свойства: dtp_ref, pay_acc_nbr и inv_unt.

$rolledbackMatches | ForEach-Object { $sqltemplate -f $_.dpt_ref, $_.pay_acc_nbr, $_.inv_unt }

person Lieven Keersmaekers    schedule 12.09.2018    source источник


Ответы (2)


На ум приходит пара подходов:

исходное назначение здесь-строки из отдельного файла:

# loop.variables.ps1
$myVar = @"
Stuff going on with $_ in here
"@

а затем в самом цикле:

1..2 | % { . .\loop.variables.ps1; <# do stuff with $myVar here #> }

Вручную вызвать расширение строки:

$hereString = @'
Stuff (not yet) going on with $_ in here
'@
1..2 | % { $myVar = $ExecutionContext.InvokeCommand.ExpandString($hereString) }

Оберните его в блок сценария

(как предложено PetSerAl)

$stringBlock = {
@"
Stuff going on with $_ in here
"@
}
1..2 | % { $myVar = &$stringBlock}
person Mathias R. Jessen    schedule 12.09.2018
comment
Решение ExpandString было тем, что я видел раньше и не мог вспомнить. Решение с блоком сценариев довольно приятное, размышляя над тем, что использовать. Спасибо вам обоим) - person Lieven Keersmaekers; 12.09.2018

Я изо всех сил пытаюсь понять, чего вы пытаетесь достичь здесь.

Для начала вы никогда не определяете здесь-строку, вы просто определяете $number как строку

Строка здесь будет выглядеть так

$number = @"
Number 4
"@

если все, что вы пытаетесь сделать, это вставить число в строку, попробуйте это

foreach ($number in (1..3)){
  "Number $number"
}

который близок к желаемому варианту и менее неоднозначен

person Richard Siddaway    schedule 12.09.2018
comment
вы правы в том, что это не строка. Эта часть была потеряна при составлении примеров, но суть осталась прежней. Ваше решение работает, но это не то, что мне нужно, тх. - person Lieven Keersmaekers; 12.09.2018