Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows PowerShell脚本不保留源文件的编码_Windows_Powershell_Encoding_Utf 8 - Fatal编程技术网

Windows PowerShell脚本不保留源文件的编码

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

我有一个非常大的源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 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(
        Unicode
        )/UTF-16BE(
        BigEndianUnicode
        )-
      • UTF-32LE(
        UTF32
        )/UTF-32BE(
        BigEndianUTF32
        )-
      • 注意缺少,但是,在实践中很少用作编码
    • 如果没有BOM,则假定默认编码

      • PowerShell[Core]v6+值得称赞地采用了UTF-8
      • 旧式Windows PowerShell(PowerShell版本至v5.1)采用ANSI编码,即旧式系统区域设置确定的代码页;e、 例如,美国英语系统上的Windows-1252
    • 文件读取cmdlet的
      -Encoding
      参数允许您明确指定源编码,但请注意,存在(受支持的)BOM会覆盖此-请参阅下文了解支持的编码

  • 在写入时,.NET字符串基于默认编码进行编码,,除非使用
    -encoding
    明确指定编码(读取时创建的.NET字符串没有关于原始输入文件编码的信息,因此无法保留):

    • PowerShell[Core]v6+很好地使用了无BOM的UTF-8

    • 遗憾的是,传统的Windows PowerShell(PowerShell直到v5.1版)使用了各种默认编码,具体取决于使用的特定cmdlet/操作符

      • 值得注意的是,
        设置内容
        默认为ANSI
        (用于阅读),而
        输出文件
        默认为UTF-16LE

        • 请参阅以获取完整图片
      • 正如js2010的回答中所指出的,在Windows PowerShell中使用
        -编码UTF8
        总是会创建具有BOM的文件,这对于Unix平台上的工具读取的文件来说可能会有问题,比如具有Unix传统的平台/工具,它们通常不具备处理此类BOM的能力

        • 有关如何在Windows PowerShell中创建无BOM表的UTF-8文件,请参阅的答案
    • 与读取一样,file writing cmdlet的
      -Encoding
      参数
      允许您显式指定输出编码:

      • 请注意,在PowerShell[Core]v6+中,除了默认为无BOM的UTF-8之外,
        -Encoding UTF8
        也指无BOM的变体(与Windows PowerShell中不同),在那里您必须使用
        -Encoding UTF8BOM
        才能创建具有BOM的文件

      • 奇怪的是,从PowerShell[Core]v7.0开始,系统的活动ANSI代码页没有
        -Encoding
        值,即Windows PowerShell的默认值(在Windows PowerShell中,
        -Encoding default
        显式请求ANSI编码,但在PowerShell[Core]中这指的是无BOM的UTF-8)。这一有问题的遗漏将在中讨论。相比之下,使用
        -编码OEM
        定位活动OEM代码页仍然有效

      • 为了创建UTF-32BE文件,Windows PowerShell需要标识符
        BigEndianUtf32
        ;由于存在,不支持此标识符,但您可以改用
        UTF-32BE

      • Windows PowerShell仅限于枚举中列出的编码,但是PowerShell[Core]允许您通过代码页码(例如
        1252
        )或编码名称(例如
        Windows-1252
        )将任何受支持的.NET编码传递给
        -Encoding参数
        [Text.Encoding]::GetEncodings().CodePage
        [Text.Encoding]::GetEncodings().Name
        原则上枚举它们,但请注意,由于此枚举只列出实际支持的编码的一小部分;在Windows PowerShell中运行这些命令将显示所有命令

      • 您可以创建UTF-7文件(
        UTF7
        ),但它们没有BOM;即使有一个输入文件,也不会在读取时自动识别,因此请指定
        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}