是否可以使用重定向运算符将输出重定向到文件,而无需在 Powershell 中写入字节顺序标记?

Is it possible to redirect output to a file using the redirection operator without writing a byte-order mark in Powershell?

有没有办法在将输出流重定向到文件时省略字节顺序标记?例如,如果我想获取一个 XML 文件的内容并用一个新值替换一个字符串,我需要创建一个新的编码并将新的输出写入一个文件,如下所示,这是相当火腿的-手数:

$newContent = ( Get-Content .\settings.xml ) -replace 'expression', 'newvalue'
$UTF8NoBom = New-Object System.Text.UTF8Encoding( $false )
[System.IO.File]::WriteAllText( '.\settings.xml', $newContent, $UTF8NoBom )

我也尝试过使用 Out-File,但指定 UTF8 因为编码仍然包含 BOM:

( Get-Content .\settings.xml ) -replace 'expression', 'newvalue' | Out-File -Encoding 'UTF8' .\settings.xml

我希望能够做的只是重定向到一个没有 BOM 的文件:

( Get-Content .\settings.xml ) -replace 'expression, 'newvalue' > settings.xml

问题是当从其他应用程序读取这些文件时,添加到输出文件的 BOM 通常会导致问题(最值得注意的是,如果我修改 XML 并且它以 BOM 开头,Chef Client 也不喜欢 JSON 属性文件中的 BOM)。除了我编写 Write-FileWithoutBom 之类的函数来接受管道输入和输出路径之外,有什么方法可以让我在将输出重定向到文件时简单地 "turn off" 编写 BOM?

解决方案不一定必须使用重定向运算符。如果有一个内置的 cmdlet 我可以用来输出到一个没有 BOM 的文件,那也是可以接受的。

  • Windows PowerShell v5.1(最新和 last 版本),没有内置方法来避免创建 BOM 使用 UTF-8 编码(缺少正如您演示的那样,直接调用 .NET 框架)。

    • 在 v5.1+ 中,您可以按如下方式更改 > / >> 的默认编码,但是如果您选择 utf8,则 仍然得到一个BOM:

      • $PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
    • 要避免 BOM,需要直接使用 .NET API - 请参阅

    • 不幸的是,Windows PowerShell 不太可能支持创建无 BOM 的 UTF-8 文件。 [1]

  • PowerShell Core (v6+),相比之下,使用 BOM-less UTF- 8 默认Out-File / >Set-Content)并为您提供 BOM 或无 BOM 选项通过 -Encoding 说明符 utf8utf8BOM.


[1] 来自 Microsoft blog post,重点添加:“Windows PowerShell 5.1,很像 .NET Framework 4.x,将继续作为 Windows 10 和 Windows Server 2016 的内置支持组件。但是,它 可能不会收到主要功能更新或较低优先级错误修复。”,并且在评论中,“PowerShell Core 6.0 和所有兼容性垫片的 目标是 取代对 Windows PowerShell 6.0,同时将生态系统融合到 PowerShell Core。所以不,我们目前 没有任何计划做 Windows PowerShell 6.0。 "