Примечание к документации: Get-Help about_Quoting_Rules
охватывает интерполяцию строк, но, начиная с PSv5, не углубленно.
Для того, чтобы дополнить полезный ответ Джой с прагматическим резюме в PowerShell в разложении строки (строка интерполяция в двойных кавычках строки ( в "...")
том числе в двойных кавычках здесь-строк ):
Только ссылки , такие как $foo
, $global:foo
(или $script:foo
, ...) и$env:PATH
(переменные среды) признаются , когда непосредственно встраивается в "..."
строке - то есть, только ссылочная переменная сама расширяется, независимо от того, что следует.
Чтобы отличить имя переменной от последующих символов в строке, заключите его в {
и}
; например, ${foo}
.
Это особенно важно , если имя переменной сопровождается :
, в PowerShell иначе бы рассмотреть все между $
и в области видимости спецификатор, как правило , вызывает интерполяцию неудачу ; например, ломается, но работает по назначению.
( В качестве альтернативы, экранирующего : ).:
"$HOME: where the heart is."
"${HOME}: where the heart is."
`
:
"$HOME`: where the heart is."
Чтобы рассматривать a $
или a "
как литерал , добавьте к нему escape-символ. `
( обратная кавычка ); например:
"`$HOME's value: `"$HOME`""
Для чего -то еще, в том числе с использованием индексов массива и доступ к переменной объекта в свойства , необходимо заключить выражение$(...)
, то оператор подвыражения (например, "PS version: $($PSVersionTable.PSVersion)"
или "1st el.: $($someArray[0])"
)
- Использование
$(...)
even позволяет вставлять вывод целых командных строк в строки с двойными кавычками (например, "Today is $((Get-Date).ToString('d'))."
).
Результаты интерполяции не обязательно выглядят так же, как формат вывода по умолчанию (то, что вы бы увидели, если бы вы напечатали переменную / подвыражение непосредственно в консоли, например, что включает средство форматирования по умолчанию; см. Get-Help about_format.ps1xml
):
Коллекции , включая массивы, преобразуются в строки путем помещения одного пробела между строковыми представлениями элементов (по умолчанию; можно указать другой разделитель путем установки $OFS
) Например, "array: $(@(1, 2, 3))"
даетarray: 1 2 3
Экземпляры любого другого типа (включая элементы коллекций, которые сами не являются коллекциями) преобразовываются в строку либо путем вызова IFormattable.ToString()
метода с инвариантной культурой , если тип экземпляра поддерживает IFormattable
интерфейс [1] , либо путем вызова .psobject.ToString()
, который в большинстве случаев просто вызывает базовый типа .NET в .ToString()
методе [2] , которые могут или не могут дать содержательное представления: если а (непримитивный) тип специально не переопределил .ToString()
метод, все , что вы получите это полное имя типа (например, "hashtable: $(@{ key = 'value' })"
выходы hashtable: System.Collections.Hashtable
).
Для того, чтобы получить тот же результат , как и в консоли , используйте подвыражения и трубуOut-String
и применить , .Trim()
чтобы удалить любые начальные и конечные пустые строки, если это необходимо; например,
"hashtable:`n$((@{ key = 'value' } | Out-String).Trim())"
дает:
hashtable:
Name Value
---- -----
key value
[1] Это, возможно, удивительное поведение означает, что для типов, которые поддерживают представления, $obj.ToString()
зависящие от языка и региональных параметров , дает представление, соответствующее текущей культуре , тогда как "$obj"
(строковая интерполяция) всегда приводит к представлению, инвариантному для культуры - см. Этот мой ответ .
[2] Важные переопределения:
* Ранее обсуждавшаяся строковая форма коллекций (разделенный пробелами список элементов, а не что-то подобное System.Object[]
).
* The hashtable- как представление [pscustomobject]
экземпляров (объяснено здесь ) , а не пустая строка .