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

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

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

更新2021

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


当前回答

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

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

其他回答

目前正确的方法是使用@Roman Kuzmin在给@M的评论中推荐的解决方案。达德利回答:

[IO.File]::WriteAllLines($filename, $content)

(我还通过去掉不必要的系统名称空间说明来缩短了它——默认情况下它将自动被替换。)

我使用的一种技术是使用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字符的保存,这不是适合您的答案。

重要!:这只适用于当一个额外的空格或换行符在开始是没有问题的文件用例 (例如,如果是SQL文件、Java文件或人类可读的文本文件)

可以结合使用创建一个空(非utf8或ASCII (utf8兼容))文件并追加它(如果源文件是一个文件,则将$str替换为gc $src):

" "    |  out-file  -encoding ASCII  -noNewline  $dest
$str  |  out-file  -encoding UTF8   -append     $dest

当一行程序

根据你的用例替换$dest和$str:

$_ofdst = $dest ; " " | out-file -encoding ASCII -noNewline $_ofdst ; $src | out-file -encoding UTF8 -append $_ofdst

作为简单函数

function Out-File-UTF8-noBOM { param( $str, $dest )
  " "    |  out-file  -encoding ASCII  -noNewline  $dest
  $str  |  out-file  -encoding UTF8   -append     $dest
}

与源文件一起使用:

Out-File-UTF8-noBOM  (gc $src),  $dest

与字符串一起使用:

Out-File-UTF8-noBOM  $str,  $dest

可选:继续追加Out-File: "more foo bar" | Out-File -encoding UTF8 -append $dest

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

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

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

使用powershell 5.1版进行测试

从版本6开始,powershell支持UTF8NoBOM编码用于设置内容和输出文件,甚至将其用作默认编码。

所以在上面的例子中,它应该是这样的:

$MyFile | Out-File -Encoding UTF8NoBOM $MyPath