我有一些PowerShell脚本在构建之前准备文件。其中一个操作是替换文件中的某些文本。我使用以下简单函数来实现此目的:
function ReplaceInFile {
Param(
[string]$file,
[string]$searchFor,
[string]$replaceWith
)
Write-Host "- Replacing '$searchFor' with '$replaceWith' in $file"
(Get-Content $file) |
Foreach-Object { $_ -replace "$searchFor", "$replaceWith" } |
Set-Content $file
}
此函数偶尔会因错误而失败:
Set-Content : Stream was not readable.
At D:\Workspace\powershell\ReplaceInFile.ps1:27 char:5
+ Set-Content $file
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (D:\Workspace\p...AssemblyInfo.cs:String) [Set-Content], ArgumentException
+ FullyQualifiedErrorId : GetContentWriterArgumentError,Microsoft.PowerShell.Commands.SetContentCommand
发生这种情况时,结果是一个空文件,一个不快乐的构建。任何想法为什么会这样?我应该做些什么?
答案 0 :(得分:6)
抱歉,我不知道为什么会发生这种情况,但您可以试试我的Replace-TextInFile
功能。如果我没记错的话,我也会使用Get-contet
来解决类似问题:
function Replace-TextInFile
{
Param(
[string]$FilePath,
[string]$Pattern,
[string]$Replacement
)
[System.IO.File]::WriteAllText(
$FilePath,
([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement)
)
}
答案 1 :(得分:2)
使用-Raw
上的Get-Content
开关将完整地读取该文件作为单个字符串。替换其中的所有值比使代码逐行迭代要快得多。
尝试
(Get-Content $file -Raw) -replace $searchFor, $replaceWith | Set-Content $file
答案 2 :(得分:1)
也许您的文件被另一个进程锁定了?您可以使用图库中的findopenfile模块来查看是否存在锁:https://www.powershellgallery.com/packages/FindOpenFile
或在sysinternals进程浏览器中搜索句柄。 https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer
答案 3 :(得分:0)
如joelsand所述,Martin Brandl的答案可以稍作改进。
function Replace-TextInFile
{
Param(
[string]$FilePath,
[string]$Pattern,
[string]$Replacement,
[System.Text.Encoding] $Encoding
)
if($Encoding) {
[System.IO.File]::WriteAllText(
$FilePath,
([System.IO.File]::ReadAllText($FilePath, $Encoding) -replace $Pattern, $Replacement),
$Encoding
)
} else {
[System.IO.File]::WriteAllText(
$FilePath,
([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement)
)
}
}
示例:
$encoding = [System.Text.Encoding]::UTF8
Replace-TextInFile -FilePath $fullPath -Pattern $pattern -Replacement $replacement -Encoding $encoding
答案 4 :(得分:0)
我遇到了这个问题,结果发现我尝试更改的文件是在Visual Studio中打开的解决方案的一部分。在运行之前关闭Visual Studio即可解决问题!