如何避免PowerShell将字符串中的$_($PSItem)当作代码解析
PowerShell中处理含
$_的字符串解析问题 我用以下PowerShell代码从文本中提取内容到$myVar:
$myVar = Select-String -Pattern '(?<=search\s=\s).*[\s*](?s).*' -input $myContent -AllMatches | Foreach {$_.matches}
$myVar的内容是包含PowerShell代码的字符串,其中偶尔会出现$_(即PowerShell的$PSItem自动变量)。后续处理$myVar时,PowerShell会把$_当作代码解析而非字符串,导致执行出错。
我试过用Regex::Escape(),但它会转义所有特殊字符,破坏字符串原有结构,导致现有处理逻辑失效。目前其他特殊字符($、^、*、+、?)都没问题,只有$_这个情况会中断流程。
以下是$myVar的典型内容片段:
bucket = testdata \ | search NOT CommandLine IN ("\"C:\\Windows\\system32\\cmd.exe\" /c PowerShell.exe -command \"get-Hotfix *\", \"\"C:\\Windows\\system32\\cmd.exe\" /c PowerShell.exe -command \"(Get-ItemProperty -Path HKLM:\\SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine -Name 'PowerShellVersion').PowerShellVersion\"\", \"\"C:\\Windows\\system32\\cmd.exe\" /c (wmic service where 'name like \"%%*%%\"' get name, startname /format:csv)\", \"\"C:\\Windows\\system32\\cmd.exe\" /c powershell -c \"(Get-Counter '\\Process(*)\\%% Processor Time').Countersamples | Where-Object cookedvalue -gt 0 | Sort-Object cookedvalue -Desc | Select-Object -First 10 | Format-Table -a instancename, @{Name='CPU %%';Expr={[Math]::Round($_.CookedValue)}}\"\",\"\"C:\\Windows\\system32\\cmd.exe\" /c powershell.exe -c \"Get-CIMInstance -Class Win32_logicaldisk | Select-Object Caption, Freespace\"")
其中;Expr={[Math]::Round($_.CookedValue)}}里的$_是问题核心。我需要一种不修改字符串内容,同时让PowerShell不将$_当作代码解析的处理方法。
解决方案:精准转义$_,避免全局修改
由于仅需处理$_这个特定自动变量,无需转义所有特殊字符,可通过字符串替换仅将$_转义为``$_(PowerShell中用反引号转义$`,即可让其被识别为字符串的一部分):
# 仅转义字符串中的$_,保留其他特殊字符 $myVarSafe = $myVar.Value -replace '\$_', '`$_'
处理后,$_会被转为``$_`,PowerShell后续处理(如输出、拼接、参数传递)时会将其视为普通字符串内容,而非自动变量解析,同时不会改变其他特殊字符的原有格式,完全兼容现有处理逻辑。
如果后续需要还原原始字符串,可反向替换:
# 还原原始字符串中的$_ $myVarOriginal = $myVarSafe -replace '`\$_', '$_'
内容的提问来源于stack exchange,提问作者Izy-
相关产品推荐
相关产品推荐

