59

为什么这不起作用?


$drvrInstFilePath = "$sharePath\$imageName\ISO`$OEM$`$1\RPKTools\RPKDriverInst.bat"
echo $drvrInstFilePath
$drvrInstContent = Get-Content -LiteralPath "$sharePath\$imageName\ISO`$OEM$`$1\RPKTools\RPKDriverInst.bat"  | Out-String

echo 显示了正确的路径,但 Get-Content 命令将 $oem 和 $1 扩展为空白字符串,即使它们被转义。为什么?

4

4 回答 4

106

不要乱用转义美元符号,而是使用单引号'而不是双引号"。它可以防止 PowerShell 扩展$为变量。像这样,

$p = "C:\temp\Share\ISO$OEM$"
# Output
C:\temp\Share\ISO$


$p = 'C:\temp\Share\ISO$OEM$'
# Output
C:\temp\Share\ISO$OEM$

如果您需要使用变量创建路径,请考虑使用Join-Path. 像这样,

$s = "Share"
join-path "C:\temp\$s" '\ISO$OEM$' 
# Output
C:\temp\Share\ISO$OEM$
于 2013-07-03T17:18:39.363 回答
32

实际上,您可以只使用刻度线来转义,$如下所示:

`$

例子:

$number = 5
Write-Host "`$${number}"
# Output: $5
于 2020-05-11T18:39:30.387 回答
20

您使用了带有单个反引号的引号。这是不正确的组合。事实上,我不确定在任何情况下单独一个反引号就足够了。在 PowerShell 中转义美元符号 ($) 的成功选择是使用带有反斜杠-反引号组合的双引号("\`$find"),或者使用带有简单反斜杠('\$find') 的单引号. [但是,请注意最后关于函数调用参数的例外情况。] 请参阅下面的示例。

此外,对于那些不熟悉区别的人,重要的是不要将这些转义中的反引号字符(`)单引号字符(')混淆。

[成功]双引号作为容器,反斜杠反引号作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\`$old", "(New)"}
What is (New)?
PS C:\Temp>

[失败]双引号作为容器,反斜杠撇号作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\'$old", "(New)"}
What is $old?
PS C:\Temp>

[SUCCESS]单引号作为容器,简单的反斜杠作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\$old', "(New)"}
What is (New)?
PS C:\Temp>

[失败]单引号作为容器,反斜杠反引号作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\`$old', "(New)"}
What is $old?
PS C:\Temp>

总的来说,最简单的选择可能是使用单引号作为容器,使用单反斜杠作为转义:'\$old'

更新:好像上面的内容还不够混乱,当您使用函数调用而不是命令时,需要单引号而不需要转义。尝试在函数调用参数上使用转义将不起作用

[失败]在函数参数中使用转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('\$old', "(New)");}
What is $old?
PS C:\Temp>

[成功]在函数参数中使用没有转义的普通单引号:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('$old', "(New)");}
What is (New)?
PS C:\Temp>
于 2015-12-28T07:52:57.893 回答
1

在我的情况下,我需要转义$字符串中使用的一些 's 而不是其他变量。

例如,我的 SSRS 实例名称有一个$符号:

[报表服务器$SSRS]

为了逃避 $ 符号,我使用单引号。否则,我使用该-join语句将变量与包含实际 $ 符号的字符串连接起来。

 $sql = -join('ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
  GO

  USE [master]
  RESTORE DATABASE [ReportServer$', $instanceName,'TempDB] FROM  DISK = N''C:\temp\ReportServerTempDB.BAK'' WITH  FILE = 1,
    MOVE N''ReportServerTempDB'' TO N''', $sqlDataDrive + "\data_" + $instanceName, '\ReportServer$', $instanceName,'TempDB.mdf'', 
    MOVE N''ReportServerTempDB_log'' TO N''', $sqlLogDrive + "\log_" + $instanceName, '\ReportServer$', $instanceName,'_TempDBlog.LDF'',  NOUNLOAD,  REPLACE, RECOVERY,  STATS = 5
  GO

  ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET MULTI_USER;
  GO
  ')
于 2018-12-13T02:53:08.417 回答