首页 > 解决方案 > 带有文本“$__VAR__”的 PowerShell 转义字符串

问题描述

我的一个脚本可以简化为以下代码。

function Replace
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory, Position=0)]
        [string]
        $LiteralPath,

        [Parameter(Mandatory, Position=1)]
        [string]
        $Expression,

        [Parameter(Mandatory, Position=2)]
        [string]
        $Replacement
    )

    Get-Content $LiteralPath | ForEach-Object {$_ -replace $Expression, $Replacement } | Set-Content $LiteralPath + ".temp"
}

对脚本的示例调用是

Replace ".\MyFile.txt" "^#define abc.*" "#define abc 1"

我遇到了需要查找和替换的字符串同时包含美元符号和下划线的情况。美元符号必须转义以防止 PowerShell 扩展变量。一个字符串包含一个美元符号,后跟一个下划线。这导致了一个问题,因为 PowerShell 没有扩展变量名称,而是扩展了$_管道变量。如何防止 PowerShell 扩展变量名和管道令牌。

这是我需要转义的字符串的函数示例。

Replace ".\MyFile.txt" "^\#\`$__LIBRARY_DIR\\prj.gpj" "`$__LIBRARY_DIR\prj.gpj"

在此示例中,读取的文本行#$__LIBRARY_DIR\prj.gpj更改为#$__LIBRARY_DIR\prj.gpj_LIBRARY_DIR\prj.gpj我正在寻找要更改为的文本$__LIBRARY_DIR\prj.gpj

请注意$_ 已扩展,我不希望它扩展。我尝试添加更多转义字符,但这只会导致它们出现在文件中。如何对字符串进行转义以防止$_扩展?

标签: powershellpowershell-5.0

解决方案


在 powershell 中,如果您不希望变量在字符串中扩展,请使用“单引号”而不是“双引号”,这样可以省去$用反引号转义符号的麻烦。

现在,在您的情况下,您面临额外的挑战,即无论您使用哪种引号,-replace操作员还希望扩展$以替换字符串中的符号开头的表达式。

要告诉-replace您真的想$在替换字符串中看到它,您需要编写$$

'#$__LIBRARY_DIR\prj.gpj' -replace '^#\$__LIBRARY_DIR\\prj.gpj','$$__LIBRARY_DIR\prj.gpj'

注意:正如其他人在评论中正确指出的那样,如果您的任务是从前导中删除表达式#,您可以以更简单的方式做到这一点:

'#$__LIBRARY_DIR\prj.gpj' -replace '^#'

或者使用旧的“修剪”:

'#$__LIBRARY_DIR\prj.gpj'.TrimStart('#')

推荐阅读