Powershell命令用于替换文件中的一块文本

时间:2011-03-22 00:23:40

标签: powershell powershell-v2.0

我正在尝试使用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 个答案:

答案 0 :(得分:9)

以下是我将如何做到这一点。首先,当您需要获取文件的全部内容(例如替换多行文本)时,请跳过Get-Content,改为使用[IO.file]::ReadAllText()。然后使用-replace运算符,例如:

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

这里我用“foo”替换开头的文字。另请注意,为了使-replace使用的正则表达式在换行符之间匹配,我在正则表达式前加(?s) - singeline模式。

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 :(得分:1)

在Get-Content中,您可以将ReadCount设置为0.这将创建一个包含1个项目的数组。您可以通过$ contents [0]

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

你也可以将整个事情传递给Out-String,但我认为第一个选项会更快一些。

答案 2 :(得分:1)

我最后做了以下事情。我发现它更容易理解。

$fileContent = [System.Io.File]::ReadAllText($filePath)
$toReplace = [System.Io.File]::ReadAllText($anotherPath)
$afterReplace = $fileContent.Replace($toReplace,$newContent)
[System.Io.Directory]::WriteAllText($filePath,$afterReplace)

答案 3 :(得分:0)

假设您的替换文字位于newscript.txt:

 $new = gc newscript.txt

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

 }

 $new | out-file newfile.sql

答案 4 :(得分:0)

脚本解决后的命令行解决方案。假设您的替换文本位于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