替换文件中的文件路径字符串

时间:2018-11-15 04:31:39

标签: regex powershell replace

我有以下脚本可获取SQL服务器的默认日志和数据位置:

[[[1 2 3 6]
  [1 2 3 4]
  [1 2 3 5]]

 [[2 2 3 6]
  [2 2 3 4]
  [2 2 3 5]]

 [[3 2 3 6]
  [3 2 3 4]
  [3 2 3 5]]]

我正在尝试在模式创建脚本的替换功能中使用$Server = '.\DEV_MIGRATIONS' $SMOServer = new-object ('Microsoft.SqlServer.Management.Smo.Server') $Server # Get the Default File Locations ### Get log and data locations $DefaultFileLocation = $SMOServer.Settings.DefaultFile $DefaultLogLocation = $SMOServer.Settings.DefaultLog if ($DefaultFileLocation.Length -eq 0) { $DefaultFileLocation = $SMOServer.Information.MasterDBPath } if ($DefaultLogLocation.Length -eq 0) { $DefaultLogLocation = $SMOServer.Information.MasterDBLogPath } $Schema_DataLocation = ($DefaultFileLocation + "Test.mdf") $Schema_DataLocation [Regex]::Escape($Schema_DataLocation) ,但是在尝试替换需要转义正则表达式的路径时遇到错误。

我从$Schema_DataLocation通话中得到的是:

[Regex]::Escape

代替:

C:\\Program\ Files\\Microsoft\ SQL\ Server\\MSSQL14\.DEV_MIGRATIONS\\MSSQL\\DATA\\Test\.mdf

替换命令:

C:\Program Files\Microsoft SQL Server\MSSQL14.DEV_MIGRATIONS\MSSQL\DATA\Test.mdf

第一个替换有效,但第二个替换失败,因为它试图匹配其他值。

删除(Get-Content $Script_SchemaCreate) | Foreach-Object { $_ -replace "DFILEPATH", $Schema_DataLocation } | Set-Content $Script_SchemaCreate (Get-Content $Script_SchemaCreate) | Foreach-Object { $_ -replace [Regex]::Escape($Schema_DataLocation), "DFILEPATH" } | Set-Content $Script_SchemaCreate 时出现以下错误:

[Regex]::Escape

1 个答案:

答案 0 :(得分:1)

不要使用[regex]::Escape()来进行-replace操作中的 replacement 字符串-它不是正则表达式,并且{ {1}}里面没有特殊含义。

相反,手动转义\个字符。之所以称为$ ,是因为$$ 确实在替换操作数中具有特殊含义,即引用匹配操作的结果,尤其是捕获组结果,例如在this answer中有详细说明。

使用$进行此手动转义有些棘手,因为-replace在正则表达式和替换操作数中都是特殊的,具有不同的转义要求:

$

因此,在这种情况下,使用字符串文字的 # Escape a string for use as the replacementt string # for another -replace call: <string> -replace '\$', '$$$$' # replace literal '$' with literal '$$' 方法 可能更简单:

.Replace()

这是一个往返示例:

<string>.Replace('$', '$$') # replace literal '$' with literal '$$'

上面产生了以下内容,证明了替换按预期进行:

$str = 'c:\program files\a-name-with-$-in-it'

# Perform substitution and output.
($new = '[DFILEPATH]' -replace 'DFILEPATH', $str.Replace('$', '$$'))

# Perform the inverse replacement.
$new -replace [regex]::Escape($str), 'DFILEPATH'