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已经发生了一些变化。检查下面的多个答案,它们有很多有用的信息!
当前回答
这个脚本将把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);
}
其他回答
使用.NET的UTF8Encoding类并将$False传递给构造函数似乎是可行的:
$MyRawString = Get-Content -Raw $MyPath
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($MyPath, $MyRawString, $Utf8NoBomEncoding)
如果你想使用[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'
这个脚本将把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);
}
更改多个文件扩展到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)
}