linux - Linux和Windows之间的文本编码

标签 linux powershell encoding decoding

我的主要问题是如何获取Linux中的文本文件以在PowerShell中正确显示。

在Linux中,我有一些特殊字符的文本文件,实际上,记事本显示的文本文件与Linux中显示的完全相同:

Notepad output

不幸的是,我的程序可以打印到Linux终端,因此我的Windows终端需要相同的输出。我通过其他答案已经看到

  • 我需要使用TrueType字体,所以我在使用Lucidia Console
  • 我的Linux设备上的
  • ,编码为UTF-8。根据我在网上可以找到的每个答案,CHCP 65001将PowerShell中的代码页切换为UTF-8
  • Windows Powershell可以更好地显示内容,因此,尽管我尝试使用命令提示符,但现在使用PowerShell。

  • 使用CHCP 65001,然后输入
    more my_file.txt
    

    显示此:

    result from more command

    在使用时
    Get-Content -Encoding UTF8 my_file.txt
    

    输出:

    result from get-content

    这些结果都不够好,但是我实际上担心Get-Content在这里所做的一切完全不同。我要传输到Windows的代码是用Free Pascal编写的,在Free Pascal中,我可以提供UTF-8代码页,仅此而已。因此,虽然Get-Content对我来说是检查PowerShell是否能够产生所需输出的好命令,但对我来说使用它并不实际。在Pascal中,输出(将写入PowerShell显示)显示为:

    Pascal Display

    同样不好的是,这些行应该连接,因为它们在Linux中使用(显然某些字符被解释为?)。但是,这可能与在Pascal中选择的代码页有关,这将是下一步。

    现在我的问题是,如何使Windows Powershell在默认情况下显示记事本版本中显示的文本文件。对我而言,到处运行代码中的Get-Content是不切实际的,因此尽管该结果看起来更有希望,但我无法遵循。

    作为后续问题,由于我无法在网上找到它,因此显示内容的主要参与者是什么,因为它显然比编码更重要。为什么“更多”和“获取内容”命令显示不同的输出?为什么“获取内容”无法读取所有内容?我以为UTF-8是一个通用标准,并且能够读取UTF-8的程序至少可以实际读取所有字符,但是他们对它们的读取方式有所不同。

    输入为文本,为:
        ╭─────╮
        │     │
      ╭─│───╮ │
      │ │   │ │
      │ │ ╭─│───╮
      │ │ │ │ │ │
    ╭─│───│─╯ │ │
    │ │ │ │   │ │
    │ │ ╰─╯   │ │
    │ │       │ │
    │ ╰───────│─╯
    │         │
    ╰─────────╯
    
    

    针对下面发布的答案,我可以看到
    more my_file.txt
    

    产生

    more command output using OutputEncoding

    使用时
    $OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = 
      New-Object System.Text.UTF8Encoding 
    

    最佳答案

  • 确保您的UTF-8编码文本文件具有BOM表-否则,Windows PowerShell会将您的文件误解为基于系统 Activity 的ANSI代码页进行编码(而现在,PowerShell [Core] 6+始终保持一致)如果没有BOM表,则默认为UTF-8)。
  • 或者,使用Get-Content -Encoding Utf8 my_file.txt显式指定文件的编码。
  • 有关Windows PowerShell与PowerShell [Core]中字符编码的全面讨论,请参见this answer
  • 要将外部程序的输出正确捕获到变量中或正确重定向到文件,您需要将[Console]::OutputEncoding设置为给定程序在输出上使用的字符编码(仅用于打印到显示器,这可能不会但是有必要):
  • 如果代码页65001(UTF-8)生效并且您的程序对此表示欢迎,则需要设置[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding;鉴于从PowerShell内部运行65001无效,因此请参见以下内容以确保chcp 65001真正有效。
  • 您提到了FreePascal,其对Unicode的支持描述为here
    但是,您的屏幕截图表明您的FreePascal程序的输出不是UTF-8,因为四舍五入的角字符已被代码转换为?字符(这表明对系统的OEM代码页进行有损代码转换,而这些字符不存在)。
  • 因此,要解决您的问题,您必须确保您的FreePascal程序无条件输出UTF-8或使用 Activity 代码页(如chcp所报告),假定您首先将其设置为65001 (UTF- 8个代码页;请参见下文)。
  • 选择一种字体,该字体可以在控制台窗口中呈现四舍五入的Unicode字符(例如( U+256D ); Windows PowerShell默认字体Lucinda Console不能(它呈现enter image description here,如您的问题所示),但是例如Consolas(默认情况下,PowerShell [Core] 6+使用的是Get-Content)可以。


    对外部程序始终使用UTF-8编码:

    注意:
  • 以下命令既不是必需的,也不会对PowerShell命令(例如more.com cmdlet)产生任何影响。
  • 某些旧版控制台应用程序-特别是more(Windows PowerShell将其包装在chcp 65001函数中)-从根本上不支持Unicode Unicode,仅支持旧版OEM代码页。[*]

  • According to every answer I can find online, CHCP 65001 switches the code page in PowerShell to UTF-8



    如果在PowerShell的
    中运行,则[Console]::OutputEncoding不起作用,因为.NET会在PowerShell session 启动时使用当时有效的代码页缓存chcp值。

    相反,您可以使用以下命令使控制台窗口完全了解UTF-8(这也将使65001之后再报告$OutputEncoding):
    $OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding =
                        New-Object System.Text.UTF8Encoding
    

    这样,PowerShell会将外部程序的输出解释为UTF-8,并且还将发送给外部程序的数据编码为UTF-8(由于使用了首选项变量65001)。

    有关更多信息,请参见this answer

    [*]启用UTF-8代码页more后,会静默跳过包含至少一个无法映射到系统OEM代码页上的Unicode字符的行(系统单字节OEM代码页中不存在的任何字符,只能代表256个字符),在这种情况下,该行适用于包含圆角字符的行,例如U+256D(框图LIGHT ARC DOWN AND RIGHT和BOX)。

    关于linux - Linux和Windows之间的文本编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60727039/

    相关文章:

    linux - 如何在 shell 脚本中获取 linux 版本集?

    c - bash 无法执行可执行文件

    java - Maven 如何确定将要运行的测试的顺序?

    python - Mac 默认 Python 路径更改

    c# - 在 ProcessRecord 中停止执行 cmdlet

    encoding - 如何生成唯一的、小的、随机的和用户友好的 key ?

    windows - powershell windows 形成浏览对话框

    windows - 如何在 Ansible 的 win_environment 模块之后更新 Windows 环境变量?

    java - 从另一个数组创建一个数组?