Заменить строку filepath в файле - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть следующий скрипт, который получает журнал по умолчанию и расположение данных для сервера SQL:

$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 Я получаю следующую ошибку:

The regular expression pattern C:\Program Files\Microsoft SQL Server\MSSQL14.DEV_MIGRATIONS\MSSQL\DATA\Migration_Data.mdf is not valid.

1 Ответ

0 голосов
/ 15 ноября 2018

Не используйте [regex]::Escape() для экранирования строки замена в операции -replace - это не регулярное выражение, и \ не имеет особого значения внутри него.

Вместо этого вручную экранирует $ символов. как $$, потому что $ имеет особое значение в операнде замены, а именно для ссылки на результаты операции сопоставления, в частности результаты группы захвата, как подробно описано в this ответить .

Выполнение этого руководства с экранированием -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'

Выше приведено следующее, доказывающее, что подстановка работала как задумано:

[c:\program files\a-name-with-$-in-it]
[DFILEPATH]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...