Out-File似乎在使用UTF-8时强制BOM:

$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "UTF8" $MyPath

我怎么能写一个文件在UTF-8没有BOM使用PowerShell?

更新2021

自从10年前我写这个问题以来,PowerShell已经发生了一些变化。检查下面的多个答案,它们有很多有用的信息!


当前回答

我在PowerShell中有相同的错误,并使用此隔离并修复了它

$PSDefaultParameterValues['*:Encoding'] = 'utf8'

其他回答

更改多个文件扩展到UTF-8没有BOM:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
foreach($i in ls -recurse -filter "*.java") {
    $MyFile = Get-Content $i.fullname 
    [System.IO.File]::WriteAllLines($i.fullname, $MyFile, $Utf8NoBomEncoding)
}

这是为我工作(使用“默认”而不是“UTF8”):

$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "Default" $MyPath

结果是没有BOM的ASCII。

我建议只使用Set-Content命令,不需要其他任何命令。

我系统中的powershell版本是:-

PS C:\Users\XXXXX> $PSVersionTable.PSVersion | fl


Major         : 5
Minor         : 1
Build         : 19041
Revision      : 1682
MajorRevision : 0
MinorRevision : 1682

PS C:\Users\XXXXX>

所以你需要跟随。

PS C:\Users\XXXXX> Get-Content .\Downloads\finddate.txt
Thursday, June 23, 2022 5:57:59 PM
PS C:\Users\XXXXX> Get-Content .\Downloads\finddate.txt | Set-Content .\Downloads\anotherfile.txt
PS C:\Users\XXXXX> Get-Content .\Downloads\anotherfile.txt
Thursday, June 23, 2022 5:57:59 PM
PS C:\Users\XXXXX>

现在,当我们检查文件,根据截图,它是utf8。 anotherfile.txt

如果你想使用[System.IO.File]::WriteAllLines(),你应该将第二个参数转换为String[](如果$MyFile的类型是Object[]),并指定绝对路径$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($MyPath),如:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
Get-ChildItem | ConvertTo-Csv | Set-Variable MyFile
[System.IO.File]::WriteAllLines($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($MyPath), [String[]]$MyFile, $Utf8NoBomEncoding)

如果你想使用[System.IO.File]::WriteAllText(),有时你应该将第二个参数管道到| Out-String |中,以显式地将crlf添加到每行的末尾(特别是当你使用ConvertTo-Csv时):

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
Get-ChildItem | ConvertTo-Csv | Out-String | Set-Variable tmp
[System.IO.File]::WriteAllText("/absolute/path/to/foobar.csv", $tmp, $Utf8NoBomEncoding)

或者你可以使用[Text.Encoding]::UTF8.GetBytes()与Set-Content -Encoding Byte:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
Get-ChildItem | ConvertTo-Csv | Out-String | % { [Text.Encoding]::UTF8.GetBytes($_) } | Set-Content -Encoding Byte -Path "/absolute/path/to/foobar.csv"

参见:如何将ConvertTo-Csv的结果写入没有BOM的UTF-8文件

使用该方法编辑UTF8-NoBOM文件,生成编码正确的文件-

$fileD = "file.xml"
(Get-Content $fileD) | ForEach-Object { $_ -replace 'replace text',"new text" } | out-file "file.xml" -encoding ASCII

起初我对这种方法持怀疑态度,但它让我感到惊讶,而且很有效!

使用powershell 5.1版进行测试