使用PowerShell,我想用MyValue替换给定文件中所有精确出现的[MYID]。最简单的方法是什么?


当前回答

我从帕耶特的Windows Powershell in Action中找到了一个鲜为人知但非常酷的方法。您可以像引用变量一样引用文件,类似于$env:path,但需要添加花括号。

${c:file.txt} = ${c:file.txt} -replace 'oldvalue','newvalue'

其他回答

我更喜欢使用。net的file类和它的静态方法,如下面的例子所示。

$content = [System.IO.File]::ReadAllText("c:\bla.txt").Replace("[MYID]","MyValue")
[System.IO.File]::WriteAllText("c:\bla.txt", $content)

这样做的优点是使用单个String,而不是像Get-Content那样使用String数组。这些方法还负责文件的编码(UTF-8 BOM等),而不需要您在大多数时候负责。

此外,与使用Get-Content和管道连接到Set-Content的算法相比,这些方法不会弄乱行结束符(可能会使用Unix行结束符)。

所以对我来说:几年下来会坏掉的东西更少。

在使用. net类时,一个鲜为人知的事情是,当您键入“[System.IO.”在PowerShell窗口中,您可以按Tab键来步进那里的方法。

对Set-Content命令的小修正。如果没有找到搜索的字符串,Set-Content命令将清空目标文件。

您可以首先验证要查找的字符串是否存在。否则,它将无法取代任何东西。

If (select-string -path "c:\Windows\System32\drivers\etc\hosts" -pattern "String to look for") `
    {(Get-Content c:\Windows\System32\drivers\etc\hosts).replace('String to look for', 'String to replace with') | Set-Content c:\Windows\System32\drivers\etc\hosts}
    Else{"Nothing happened"}

我从帕耶特的Windows Powershell in Action中找到了一个鲜为人知但非常酷的方法。您可以像引用变量一样引用文件,类似于$env:path,但需要添加花括号。

${c:file.txt} = ${c:file.txt} -replace 'oldvalue','newvalue'

使用PowerShell中的当前工作目录,这对我来说很有效。您需要使用FullName属性,否则它将在PowerShell版本5中不起作用。我需要在所有CSPROJ文件中更改目标. net框架版本。

gci -Recurse -Filter *.csproj |
% { (get-content "$($_.FullName)")
.Replace('<TargetFramework>net47</TargetFramework>', '<TargetFramework>net462</TargetFramework>') |
 Set-Content "$($_.FullName)"}

用途(V3版本):

(Get-Content c:\temp\test.txt).replace('[MYID]', 'MyValue') | Set-Content c:\temp\test.txt

对于V2:

(Get-Content c:\temp\test.txt) -replace '\[MYID\]', 'MyValue' | Set-Content c:\temp\test.txt