如何在双引号字符串中使用对象的属性?
我有以下代码:
$DatabaseSettings = @();
$NewDatabaseSetting = "" | select DatabaseName, DataFile, LogFile, LiveBackupPath;
$NewDatabaseSetting.DatabaseName = "LiveEmployees_PD";
$NewDatabaseSetting.DataFile = "LiveEmployees_PD_Data";
$NewDatabaseSetting.LogFile = "LiveEmployees_PD_Log";
$NewDatabaseSetting.LiveBackupPath = '\\LiveServer\LiveEmployeesBackups';
$DatabaseSettings += $NewDatabaseSetting;
当我尝试使用字符串执行命令中的属性之一时:
& "$SQlBackupExePath\SQLBackupC.exe" -I $InstanceName -SQL `
"RESTORE DATABASE $DatabaseSettings[0].DatabaseName FROM DISK = '$tempPath\$LatestFullBackupFile' WITH NORECOVERY, REPLACE, MOVE '$DataFileName' TO '$DataFilegroupFolder\$DataFileName.mdf', MOVE '$LogFileName' TO '$LogFilegroupFolder\$LogFileName.ldf'"
它尝试仅使用 $DatabaseSettings
的值,而不是 $DatabaseSettings[0 ].DatabaseName
,无效。
我的解决方法是将其复制到一个新变量中。
如何直接在双引号字符串中访问对象的属性?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当您将变量名称括在双引号字符串中时,它将被该变量的值替换:
变为
如果您不希望必须使用单引号:
但是,如果您想访问属性或使用变量上的索引在双引号字符串中,您必须将该子表达式括在
$()
中:在这些情况下,PowerShell 仅扩展变量,仅此而已。要强制计算更复杂的表达式(包括索引、属性甚至完整计算),您必须将它们括在子表达式运算符
$( )
中,这会导致内部表达式被计算并嵌入到字符串中。When you enclose a variable name in a double-quoted string it will be replaced by that variable's value:
becomes
If you don't want that you have to use single quotes:
However, if you want to access properties, or use indexes on variables in a double-quoted string, you have to enclose that subexpression in
$()
:PowerShell only expands variables in those cases, nothing more. To force evaluation of more complex expressions, including indexes, properties or even complete calculations, you have to enclose those in the subexpression operator
$( )
which causes the expression inside to be evaluated and embedded in the string.文档注:
got>
覆盖字符串插值,但从psv5开始,不是深度。get-help of_quoting_rules
补充乔伊的乐于助人的答案使用PowerShell的 字符串扩展的务实摘要 (双引号 strings中的字符串插值(
”。 ..“
,又名 可扩展的字符串 ),包括在双引号 there-scrings ):仅引用,例如
$ foo
,,<代码> $ global:foo (或$ script:foo
,...)和$ env:路径
(环境变量)可以直接 嵌入“ ...”
string - 也就是说,只有变量参考本身,总体被扩展,不论下面的内容如何。eg,
“ $ home.foo”
扩展到c:\ users \ jdoe.foo.foo
,因为.foo
代码>部分被解释字面上的 - 不是作为属性访问。to 将变量名称删除字符串中后续字符的变量名称,将其包含在
{
and 和}
;例如,$ {foo}
。如果变量名是
:
,那么这一点尤其重要,因为PowerShell否则会考虑$
和: a a 之间的所有内容>范围指示符,通常导致插值 fail ;例如,<代码>“ $ home:心脏在哪里。” 中断,但“ $ {home}:心脏在哪里。”
按预期工作。(或者,
`
-escape:
:“ $ home”:心脏在哪里。然后,变量名不会意外地形成 evase sequence ,然后使用前面的
`
,例如`b
- 请参阅概念 ail_special_characters about_special_characters将
(a backtick );
$
或“
”作为 字面的,将其与 Escape Char一起前缀。“`$ home的价值:$ home'
其他任何事物,包括使用 array subscripts 并访问对象变量的 properties ,您必须将表达式包裹在
$(...)
,$(...)
甚至允许您从中嵌入整个命令中的输出(例如(get-tate).toString('d'))。” )。插值结果看起来不一定与默认输出格式< / strong>(如果您直接将变量 /子表达打印到控制台,涉及默认格式格式) ;请参阅 ):
集合,包括数组,通过在元素的字符串表示之间放置A 单个空间(通过默认;可以通过设置偏好变量
$ ofs
,尽管在实践中很少见到),例如,“ array:$(@(1,2,2,3) )“
产量数组:1 2 3
的实例(包括非收藏集的集合的元素) 都调用
iformattable.tostring.toString()
使用不变文化的方法,如果实例的类型支持iformattable
接口> interface [1] ,或或通过调用.psobject.tostring()
,在大多数情况下,它只是调用基本的.NET类型的.toString()
method> method> method> [2] [2] ,它可能会或可能不会给出有意义的表示:除非有(非重要性)类型已专门覆盖.toString()
方法,否则您所得到的只是完整的键入名称(例如,“ hashtable:$(@{key ='value'})”
产量hashtable:system.collections.hashtable
)。<<<<<<<<<<<<<<<<<<< /p>to 获得与 console 中相同的输出,请使用管道到
out-string 并应用
。 trim()
如果需要,请删除任何前导和尾随的空线;例如,“ hashtable:`n $((@{key ='value'} | out-string).trim())”
屈服:[1]这也许令人惊讶的行为意味着,对于,对于,支持文化敏感表示的类型,
$ obj.tostring()
产生a 当前 cultulture-适当表示,而“ $ obj”
(字符串插值)始终导致A culture -invariant 表示 - 请参见这个答案。 >[2]值得注意的覆盖:
• collections 的先前讨论的弦乐(元素的空格分隔列表,而不是
system.Object.Object []
)。•
[pscustomObject]
instances(解释)而不是空字符串。Documentation note:
Get-Help about_Quoting_Rules
covers string interpolation, but, as of PSv5, not in-depth.To complement Joey's helpful answer with a pragmatic summary of PowerShell's string expansion (string interpolation in double-quoted strings (
"..."
, a.k.a. expandable strings), including in double-quoted here-strings):Only references such as
$foo
,$global:foo
(or$script:foo
, ...) and$env:PATH
(environment variables) can directly be embedded in a"..."
string - that is, only the variable reference itself, as a whole is expanded, irrespective of what follows.E.g.,
"$HOME.foo"
expands to something likeC:\Users\jdoe.foo
, because the.foo
part was interpreted literally - not as a property access.To disambiguate a variable name from subsequent characters in the string, enclose it in
{
and}
; e.g.,${foo}
.This is especially important if the variable name is followed by a
:
, as PowerShell would otherwise consider everything between the$
and the:
a scope specifier, typically causing the interpolation to fail; e.g.,"$HOME: where the heart is."
breaks, but"${HOME}: where the heart is."
works as intended.(Alternatively,
`
-escape the:
:"$HOME`: where the heart is."
, but that only works if the character following the variable name wouldn't then accidentally form an escape sequence with a preceding`
, such as`b
- see the conceptual about_Special_Characters help topic).To treat a
$
or a"
as a literal, prefix it with escape char.`
(a backtick); e.g.:"`$HOME's value: $HOME"
For anything else, including using array subscripts and accessing an object variable's properties, you must enclose the expression in
$(...)
, the subexpression operator (e.g.,"PS version: $($PSVersionTable.PSVersion)"
or"1st el.: $($someArray[0])"
)$(...)
even allows you to embed the output from entire commands in double-quoted strings (e.g.,"Today is $((Get-Date).ToString('d'))."
).Interpolation results don't necessarily look the same as the default output format (what you'd see if you printed the variable / subexpression directly to the console, for instance, which involves the default formatter; see
Get-Help about_format.ps1xml
):Collections, including arrays, are converted to strings by placing a single space between the string representations of the elements (by default; a different separator can be specified by setting preference variable
$OFS
, though that is rarely seen in practice) E.g.,"array: $(@(1, 2, 3))"
yieldsarray: 1 2 3
Instances of any other type (including elements of collections that aren't themselves collections) are stringified by either calling the
IFormattable.ToString()
method with the invariant culture, if the instance's type supports theIFormattable
interface[1], or by calling.psobject.ToString()
, which in most cases simply invokes the underlying .NET type's.ToString()
method[2], which may or may not give a meaningful representation: unless a (non-primitive) type has specifically overridden the.ToString()
method, all you'll get is the full type name (e.g.,"hashtable: $(@{ key = 'value' })"
yieldshashtable: System.Collections.Hashtable
).To get the same output as in the console, use a subexpression in which you pipe to
Out-String
and apply.Trim()
to remove any leading and trailing empty lines, if desired; e.g.,"hashtable:`n$((@{ key = 'value' } | Out-String).Trim())"
yields:[1] This perhaps surprising behavior means that, for types that support culture-sensitive representations,
$obj.ToString()
yields a current-culture-appropriate representation, whereas"$obj"
(string interpolation) always results in a culture-invariant representation - see this answer.[2] Notable overrides:
• The previously discussed stringification of collections (space-separated list of elements rather than something like
System.Object[]
).• The hashtable-like representation of
[pscustomobject]
instances (explained here) rather than the empty string.@Joey有正确的答案,但只是要添加更多有关为什么需要用
$()
来强制评估的更多信息:您的示例代码包含一个模棱两可,指出了PowerShell的制造商为什么可以选择将扩展限制为单纯的变量引用,而不支持对属性的访问(作为一边:字符串扩展是通过在对象上调用
toString()
方法来完成的,可以在对象上解释一些“奇数” “ 结果)。您的示例包含在命令行的末尾:
如果默认情况下扩展了对象的属性,则以上将解决到
$ logfilename
> logfilename 的对象,将不会具有称为ldf的属性
,$ null
(或一个空字符串)将被替换为变量。@Joey has the correct answer, but just to add a bit more as to why you need to force the evaluation with
$()
:Your example code contains an ambiguity that points to why the makers of PowerShell may have chosen to limit expansion to mere variable references and not support access to properties as well (as an aside: string expansion is done by calling the
ToString()
method on the object, which can explain some "odd" results).Your example contained at the very end of the command line:
If properties of objects were expanded by default, the above would resolve to
since the object referenced by
$LogFileName
would not have a property calledldf
,$null
(or an empty string) would be substituted for the variable.@Joey有一个很好的答案。还有另一种方式,带有字符串。Format等效的更数。当对象上访问属性时,我更喜欢它:
关于汽车的事物:
创建对象:
插值字符串:
输出:输出:
@Joey has a good answer. There is another way with a more .NET look with a String.Format equivalent, I prefer it when accessing properties on objects:
Things about a car:
Create an object:
Interpolate a string:
Outputs:
如果您想在报价中使用属性,请如下所示。您必须在支架外使用$以打印属性。
示例:
输出:
如果仅想要名称属性,则如下:
输出:
If you want to use properties within quotes follow as below. You have to use $ outside of the bracket to print property.
Example:
Output:
If you want only name property then do as below:
Output: