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

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

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

更新2021

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


当前回答

更改多个文件扩展到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)
}

其他回答

更改多个文件扩展到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)
}

使用.NET的UTF8Encoding类并将$False传递给构造函数似乎是可行的:

$MyRawString = Get-Content -Raw $MyPath
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($MyPath, $MyRawString, $Utf8NoBomEncoding)

当使用Set-Content而不是Out-File时,可以指定encoding Byte,它可用于将字节数组写入文件。这与不发出BOM的自定义UTF8编码相结合,给出了所需的结果:

# This variable can be reused
$utf8 = New-Object System.Text.UTF8Encoding $false

$MyFile = Get-Content $MyPath -Raw
Set-Content -Value $utf8.GetBytes($MyFile) -Encoding Byte -Path $MyPath

与使用[IO.File]::WriteAllLines()或类似方法的区别在于,它应该适用于任何类型的项和路径,而不仅仅是实际的文件路径。

可以使用下面得到UTF8没有BOM

$MyFile | Out-File -Encoding ASCII

我认为这不会是UTF,但我只是发现了一个相当简单的解决方案,似乎工作…

Get-Content path/to/file.ext | out-file -encoding ASCII targetFile.ext

对我来说,这导致了一个没有bom文件的utf-8,不管源格式如何。