Команда Powershell для замены фрагмента текста в файле - PullRequest
4 голосов
/ 22 марта 2011

Я пытаюсь заменить кусок текста в файле с помощью powershell. Например, у меня есть файл .sql, и я знаю точный кусок сценария SQL, который необходимо заменить в этом конкретном файле. После прочтения некоторых примеров замены powershell похоже, что powershell возвращает содержимое файла в массиве (каждая строка представляет одну запись в массиве).

Например:

GO
:on error exit
GO
IF (DB_ID(N'$(DatabaseName)') IS NOT NULL) 
BEGIN
    ALTER DATABASE [$(DatabaseName)]
    SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE [$(DatabaseName)];
END

GO
PRINT N'Creating $(DatabaseName)...'
GO
CREATE DATABASE [$(DatabaseName)] COLLATE SQL_Latin1_General_CP1_CI_AS
GO

USE [$(DatabaseName)]
.......
.........
..... MORE SQL SCRIPT

Я хочу заменить текст до USE [$ (DatabaseName)] в вышеуказанном файле.

Спасибо.

Ответы [ 5 ]

9 голосов
/ 22 марта 2011

Вот как бы я поступил по этому поводу. Во-первых, когда вам нужно получить все содержимое файла для таких целей, как замена текста на несколько строк, пропустите, используя Get-Content, вместо этого используйте [IO.file]::ReadAllText(). Затем используйте оператор -replace, например ::100100

[IO.File]::ReadAllText("$pwd\foo.sql") -replace `
   '(?s).*?(USE \[\$\(DatabaseName\)\].*)$',"foo`n`$1" > foo.sql

Здесь я заменяю начальный текст на "foo". Также обратите внимание, что чтобы получить регулярное выражение, используемое -replace для сопоставления по новым строкам, я добавляю к регулярному выражению (?s) - одиночный режим.

Mjolinor поднимает хороший вопрос, если в тексте замены есть символы, которые можно интерпретировать как специальные переменные регулярного выражения, например, $1, $2 и т. Д. Хотя вы можете использовать [regex]::escape() для выхода из регулярного выражения, есть еще PowerShell, который будет интерпретировать $<something> как переменную или начало подвыражения. В этом случае обойти это довольно просто, просто захватив часть, которую вы хотите сохранить, с помощью оператора -replace, а затем добавьте новый текст на втором шаге, например ::

$keep = [IO.File]::ReadAllText("$pwd\foo.sql") -replace `
            '(?s).*?(USE \[\$\(DatabaseName\)\].*)$','$1'
$newText + $keep > foo.sql

Обратите внимание, что при замене в этом случае я использую одинарные кавычки вокруг $1, что не позволяет PowerShell интерпретировать любые специальные символы PowerShell. Это похоже на дословную строку в C #.

1 голос
/ 22 марта 2011

Я закончил тем, что делал ниже. Мне это легче понять.

$fileContent = [System.Io.File]::ReadAllText($filePath)
$toReplace = [System.Io.File]::ReadAllText($anotherPath)
$afterReplace = $fileContent.Replace($toReplace,$newContent)
[System.Io.Directory]::WriteAllText($filePath,$afterReplace)
1 голос
/ 22 марта 2011

В Get-Content вы можете установить ReadCount равным 0. Это создаст массив из 1 элемента. Вы можете получить к нему доступ через $ contents [0]

$contents = get-content file.sql -readcount 0
$contents[0].Replace($oldstring,$newString)

Вы также можете передать все это на Out-String, но я думаю, что первый вариант будет немного быстрее.

0 голосов
/ 22 марта 2011

После решения сценария решение командной строки.Предполагая, что ваш текст замены находится в newscript.txt

# Read the file $file is an array of lines
PS > $file = Get-Content 'C:\temp\sql.txt'

# retreive the line begining the replacement
PS > $begin  =  $file | Select-String -Pattern 'USE \[\$\(DatabaseName\)\]' 
PS > $begin.linenumber
17

# Selecting (in a new array) the last comuted lines
PS > $secondPart = $file | Select-Object -Last ($file.count - $begin.linenumber +1) 
PS > $secondPart
USE [$(DatabaseName)]
.......
.........
..... MORE SQL SCRIPT

# Creating the new file
PS > $new = gc newscript.txt
PS > ($new + $secondPart) | out-file newfile.sql

Я надеюсь, что это поможет

JP

0 голосов
/ 22 марта 2011

Если ваш замещающий текст находится в файле newscript.txt:

 $new = gc newscript.txt

 get-content file.sql |% {
 if ($_ -eq 'USE [$(DatabaseName)]') {$test = $true}
 if ($test) {$new += $_}

 }

 $new | out-file newfile.sql
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...