Windows PowerShell脚本不保留源文件的编码
我有一个非常大的源csv文件,为了能够更有效地使用它,我决定将它分割成更小的文件块。为此,我执行以下脚本:Windows PowerShell脚本不保留源文件的编码,windows,powershell,encoding,utf-8,Windows,Powershell,Encoding,Utf 8,我有一个非常大的源csv文件,为了能够更有效地使用它,我决定将它分割成更小的文件块。为此,我执行以下脚本: Get-Content C:\Users\me\Desktop\savedDataframe.csv -ReadCount 250000 | %{$i++; $_ | Out-File C:\Users\me\Desktop\Processed\splitfile_$i.csv} 如您所见,这些是包含字母数字数据的csv文件。所以,我有一个类似于这个字符串的问题: Hämeenkatu
Get-Content C:\Users\me\Desktop\savedDataframe.csv -ReadCount 250000 | %{$i++; $_ | Out-File C:\Users\me\Desktop\Processed\splitfile_$i.csv}
如您所见,这些是包含字母数字数据的csv文件。所以,我有一个类似于这个字符串的问题:
Hämeenkatu 33
在目标文件中,它如下所示:
H÷meenkatu 33
我试图确定源文件的编码,它是UTF-8(如上所述)。我真的很想知道为什么它会在目标中变得如此混乱。我还尝试了以下方法来明确说明我希望编码为UTF8,但没有成功:
Get-Content C:\Users\me\Desktop\savedDataframe.csv -ReadCount 250000 | %{$i++; $_ | Out-File -Encoding "UTF8" C:\Users\me\Desktop\Processed\splitfile_$i.csv}
我使用的是运行Windows 10的Windows计算机。输入文件是否有bom表?尝试
获取内容-编码utf8
。Out文件默认为utf16le或windows和powershell所称的“unicode”
除非您使用powershell 6或7,否则输出文件将具有bom。提供了有效的解决方案;让我补充一下背景信息(手边案件的摘要在底部):
基本上,PowerShell从不在输出时保留[文本]输入文件的字符编码:
- 读取时,将文件内容解码为.NET字符串(内部为UTF-16代码单元):
- 以下编码的带有BOM的文件始终被正确识别(括号中PowerShell cmdlet的
参数识别的标识符):-Encoding
- UTF-8(
)-UTF8
- UTF-16LE(
)/UTF-16BE(Unicode
)-BigEndianUnicode
- UTF-32LE(
)/UTF-32BE(UTF32
)-BigEndianUTF32
- 注意缺少,但是,在实践中很少用作编码
- UTF-8(
- 如果没有BOM,则假定默认编码
- PowerShell[Core]v6+值得称赞地采用了UTF-8
- 旧式Windows PowerShell(PowerShell版本至v5.1)采用ANSI编码,即旧式系统区域设置确定的代码页;e、 例如,美国英语系统上的Windows-1252
- 以下编码的带有BOM的文件始终被正确识别(括号中PowerShell cmdlet的
- 文件读取cmdlet的
参数允许您明确指定源编码,但请注意,存在(受支持的)BOM会覆盖此-请参阅下文了解支持的编码-Encoding
-encoding
明确指定编码(读取时创建的.NET字符串没有关于原始输入文件编码的信息,因此无法保留):
- PowerShell[Core]v6+很好地使用了无BOM的UTF-8
- 遗憾的是,传统的Windows PowerShell(PowerShell直到v5.1版)使用了各种默认编码,具体取决于使用的特定cmdlet/操作符
- 值得注意的是,
默认为ANSI(用于阅读),而设置内容
默认为UTF-16LE输出文件
- 请参阅以获取完整图片
- 正如js2010的回答中所指出的,在Windows PowerShell中使用
总是会创建具有BOM的文件,这对于Unix平台上的工具读取的文件来说可能会有问题,比如具有Unix传统的平台/工具,它们通常不具备处理此类BOM的能力-编码UTF8
- 有关如何在Windows PowerShell中创建无BOM表的UTF-8文件,请参阅的答案
- 值得注意的是,
- 与读取一样,file writing cmdlet的
参数允许您显式指定输出编码:-Encoding
- 请注意,在PowerShell[Core]v6+中,除了默认为无BOM的UTF-8之外,
也指无BOM的变体(与Windows PowerShell中不同),在那里您必须使用-Encoding UTF8
才能创建具有BOM的文件-Encoding UTF8BOM
- 奇怪的是,从PowerShell[Core]v7.0开始,系统的活动ANSI代码页没有
值,即Windows PowerShell的默认值(在Windows PowerShell中,-Encoding
显式请求ANSI编码,但在PowerShell[Core]中这指的是无BOM的UTF-8)。这一有问题的遗漏将在中讨论。相比之下,使用-Encoding default
定位活动OEM代码页仍然有效-编码OEM
- 为了创建UTF-32BE文件,Windows PowerShell需要标识符
;由于存在,不支持此标识符,但您可以改用BigEndianUtf32
UTF-32BE
- Windows PowerShell仅限于枚举中列出的编码,但是PowerShell[Core]允许您通过代码页码(例如
)或编码名称(例如1252
)将任何受支持的.NET编码传递给Windows-1252
参数-Encoding
和[Text.Encoding]::GetEncodings().CodePage
原则上枚举它们,但请注意,由于此枚举只列出实际支持的编码的一小部分;在Windows PowerShell中运行这些命令将显示所有命令[Text.Encoding]::GetEncodings().Name
- 您可以创建UTF-7文件(
),但它们没有BOM;即使有一个输入文件,也不会在读取时自动识别,因此请指定UTF7
Get-Content -encoding utf8 C:\Users\me\Desktop\savedDataframe.csv -ReadCount 250000 | %{$i++; $_ | Out-File -encoding utf8 C:\Users\me\Desktop\Processed\splitfile_$i.csv}
- 请注意,在PowerShell[Core]v6+中,除了默认为无BOM的UTF-8之外,