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

エコーは正しいパスを示しますが、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 に答える
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>

[成功]エスケープとして単純なバックスラッシュを含むコンテナとしての一重引用符:

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

私の場合$、文字列で使用されている一部の をエスケープする必要がありましたが、変数である他のものはエスケープする必要がありませんでした。

たとえば、私の SSRS インスタンス名には$記号があります。

[ReportServer$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 に答える