我正在尝试使用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)]。
感谢。
答案 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