代码之家  ›  专栏  ›  技术社区  ›  caveman_dick

如何在双引号字符串中使用对象的属性?

  •  73
  • caveman_dick  · 技术社区  · 17 年前

    $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 ,这是无效的。

    如何在双引号字符串中直接访问对象的属性?

    4 回复  |  直到 9 年前
        1
  •  194
  •   Robert Dyjas Joey    7 年前

    将变量名括在双引号字符串中时,它将替换为该变量的值:

    $foo = 2
    "$foo"
    

    变成

    "2"
    

    $foo = 2
    '$foo'
    

    但是,如果您想访问属性,或者对双引号字符串中的变量使用索引,则必须将该子表达式括在 $() :

    $foo = 1,2,3
    "$foo[1]"     # yields "1 2 3[1]"
    "$($foo[1])"  # yields "2"
    
    $bar = "abc"
    "$bar.Length"    # yields "abc.Length"
    "$($bar.Length)" # yields "3"
    

    PowerShell仅在这些情况下扩展变量,仅此而已。要强制计算更复杂的表达式,包括索引、属性甚至完整的计算,必须将这些表达式包含在subexpression操作符中 $( ) 这将导致内部表达式被计算并嵌入字符串中。

        2
  •  16
  •   prakash    9 年前

    @乔伊给出了正确的答案,但只是想补充一点,为什么你需要用 $() :

    您的示例代码包含一个模棱两可的地方,说明了为什么PowerShell的制造商可能选择将扩展限制为仅变量引用,而不支持对属性的访问(顺便说一句:字符串扩展是通过调用 ToString() 方法,它可以解释一些“奇怪”的结果)。

    您的示例包含在命令行的末尾:

    ...\$LogFileName.ldf
    

    ...\
    

    由于 $LogFileName 不会有一个名为 ldf $null (或空字符串)将被替换为变量。

        3
  •  14
  •   mklement0    5 年前

    文件说明: Get-Help about_Quoting_Rules

    补充 Joey's helpful answer 语用总结 PowerShell的 (字符串插值) 双引号 弦( "..." ,又称。 ),包括双引号 here-strings

    • 仅参考,例如 $foo , $global:foo (或 $script:foo ,…)和 $env:PATH (环境变量) 可以 直接地 嵌入 一串 只有变量引用 扩大 ,而不论下文如何。

      • "$HOME.foo" 扩展到类似 C:\Users\jdoe.foo

      • 消除变量名的歧义 从字符串中的后续字符, 把它包起来 { } ; 例如。, ${foo}
        : $ : 范围 失败 ; 例如。, "$HOME: where the heart is." "${HOME}: where the heart is." 按预期工作。
        ` -逃离 : : "$HOME`: where the heart is." 逃逸序列 有前导 ` `b -见概念图 about_Special_Characters 帮助主题)。

      • 治疗 或者 " 作为一个 字面意义的 逃逸字符。 ` (一) 背勾
        "`$HOME's value: $HOME"

    • 对于其他任何事情,包括使用 数组下标 性质 将表达式括在 $(...) 这个 subexpression operator (例如:。, "PS version: $($PSVersionTable.PSVersion)" "1st el.: $($someArray[0])" )

      • 使用 甚至允许您将整个命令行的输出嵌入双引号字符串中(例如。, "Today is $((Get-Date).ToString('d'))."
    • 插值结果不一定与默认输出格式相同 Get-Help about_format.ps1xml ):

      • 收藏 ,包括数组,通过 放置 单一空间 (默认情况下,可以通过设置指定不同的分隔符。) preference variable $OFS ,尽管这在实践中很少见到)例如。, "array: $(@(1, 2, 3))" 产量 array: 1 2 3

      • 实例 任何其他类型 任何一个 呼叫 IFormattable.ToString() 方法与 不变培养 IFormattable 界面 , .psobject.ToString() ,在大多数情况下,它只是调用底层.NET类型的 .ToString() ,它可能给出也可能不给出有意义的表示:除非(非原语)类型已明确重写 .ToString() 类型名 (例如:。, "hashtable: $(@{ key = 'value' })" hashtable: System.Collections.Hashtable

      • 安慰 ,使用一个子表达式,其中 Out-String 申请 .Trim()
        "hashtable:`n$((@{ key = 'value' } | Out-String).Trim())" 产量:

            hashtable:                                                                                                                                                                          
            Name                           Value                                                                                                                                               
            ----                           -----                                                                                                                                               
            key                            value      
        

    $obj.ToString() 产生 现在的 "$obj" (字符串插值)始终导致 文化不变量 代表性-见 this answer

    [2] 值得注意的覆盖:
    收藏 (以空格分隔的元素列表,而不是类似 System.Object[] ).
    哈希表- 代表 [pscustomobject] 实例(已解释) here )而不是 .

        4
  •  10
  •   loonison101    10 年前

    @乔伊有一个很好的答案。另一种方法是使用与String.Format等效的.NET外观,我更喜欢在访问对象属性时使用它:

    关于汽车的事情:

    $properties = @{ 'color'='red'; 'type'='sedan'; 'package'='fully loaded'; }
    

    创建一个对象:

    $car = New-Object -typename psobject -Property $properties
    

    插入字符串:

    "The {0} car is a nice {1} that is {2}" -f $car.color, $car.type, $car.package
    

    产出:

    # The red car is a nice sedan that is fully loaded
    
    推荐文章