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

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

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

更新2021

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


当前回答

我使用的一种技术是使用Out-File cmdlet将输出重定向到ASCII文件。

例如,我经常运行创建另一个SQL脚本并在Oracle中执行的SQL脚本。使用简单的重定向(“>”),输出将是SQLPlus无法识别的UTF-16格式。要解决这个问题:

sqlplus -s / as sysdba "@create_sql_script.sql" |
Out-File -FilePath new_script.sql -Encoding ASCII -Force

生成的脚本可以通过另一个SQLPlus会话执行,而无需担心Unicode:

sqlplus / as sysdba "@new_script.sql" |
tee new_script.log

更新:正如其他人指出的那样,这会删除非ascii字符。由于用户要求一种“强制”转换的方法,我假设他们并不关心这一点,因为他们的数据可能不包含这样的数据。

如果您关心非ascii字符的保存,这不是适合您的答案。

其他回答

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

$MyFile | Out-File -Encoding ASCII

这个脚本将把DIRECTORY1中的所有.txt文件转换为不含BOM的UTF-8格式,并将它们输出到DIRECTORY2

foreach ($i in ls -name DIRECTORY1\*.txt)
{
    $file_content = Get-Content "DIRECTORY1\$i";
    [System.IO.File]::WriteAllLines("DIRECTORY2\$i", $file_content);
}

对于PowerShell 5.1,启用此设置:

控制面板,区域,管理,更改系统区域,使用Unicode UTF-8 全球语言支持

然后输入PowerShell:

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

或者,您可以升级到PowerShell 6或更高版本。

https://github.com/PowerShell/PowerShell

当使用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()或类似方法的区别在于,它应该适用于任何类型的项和路径,而不仅仅是实际的文件路径。

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

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

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