Out-File似乎在使用UTF-8时强制BOM:
$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "UTF8" $MyPath
我怎么能写一个文件在UTF-8没有BOM使用PowerShell?
更新2021
自从10年前我写这个问题以来,PowerShell已经发生了一些变化。检查下面的多个答案,它们有很多有用的信息!
Out-File似乎在使用UTF-8时强制BOM:
$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "UTF8" $MyPath
我怎么能写一个文件在UTF-8没有BOM使用PowerShell?
更新2021
自从10年前我写这个问题以来,PowerShell已经发生了一些变化。检查下面的多个答案,它们有很多有用的信息!
当前回答
使用该方法编辑UTF8-NoBOM文件,生成编码正确的文件-
$fileD = "file.xml"
(Get-Content $fileD) | ForEach-Object { $_ -replace 'replace text',"new text" } | out-file "file.xml" -encoding ASCII
起初我对这种方法持怀疑态度,但它让我感到惊讶,而且很有效!
使用powershell 5.1版进行测试
其他回答
目前正确的方法是使用@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字符的保存,这不是适合您的答案。
如果你想使用[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文件
我在PowerShell中有相同的错误,并使用此隔离并修复了它
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
从版本6开始,powershell支持UTF8NoBOM编码用于设置内容和输出文件,甚至将其用作默认编码。
所以在上面的例子中,它应该是这样的:
$MyFile | Out-File -Encoding UTF8NoBOM $MyPath