【问题标题】:UTF8 output from Strawberry PerlStrawberry Perl 的 UTF8 输出
【发布时间】:2021-05-22 12:40:47
【问题描述】:

我有一个文本文件 test.txt,其中包含 UTF8 编码内容 äöü(这些是德语变音符号,只是一个示例,文件大小为 6 字节)。我在 Windows 10 PC 上还有一个具有正确 LANG 设置的 Cygwin 终端:

$ cat test.txt
äöü

我想用 Perl 脚本打印此文件的内容,但无法正常工作。

open my $fh, '<', 'test.txt';
print <$fh>;
close $fh;

结果

$ perl test.pl
├ñ├Â├╝

我尝试了在How can I output UTF-8 from Perl? 找到的所有变体——它们都没有解决我的问题。怎么了?

根据请求进行编辑:

$ file test.txt
test.txt: UTF-8 Unicode text, with no line terminators

$ echo $LANG

我还尝试将 LANG 设置为 de_DE.UTF-8

编辑缩小问题范围:如果我尝试使用 Cygwin 中包含的 Perl 版本 5.32.1,它会按预期工作。它在Strawberry Perl 5.32.1 版中仍然不起作用。所以这可能不是 Perl 问题,也不是 Windows 问题,也不是语言或编码设置的问题,而是 Strawberry Perl 问题。

【问题讨论】:

  • 它对我有用。所以你身边有一个encoding 问题。 file test.txtecho $LANG 的输出是什么?如果您确定编码,您可以使用iconv 进行转换。
  • 感谢您的尝试。我编辑了我的问题并添加了您的命令的结果。
  • 以下3个命令给你什么:od -t x1 test.txt;猫测试.txt | od -t x1; perl 测试.pl | od -t x1
  • 感谢这个想法。它给出了三倍“0000000 c3 a4 c3 b6 c3 bc”。脚本接缝的输出正常,但 cat test.txt 有效,perl test.pl 无效。
  • @HåkonHægland:我试过这个,它奏效了。我还尝试了 Cygwin Perl 版本 5.32.1,这也有效。但是对于 Strawberry Perl 5.32.1 版本,它不起作用。所以,这不是 Perl 问题,也不是 Windows 问题——这是 Strawberry 环境的问题。非常感谢!

标签: perl utf-8 cygwin


【解决方案1】:
$ "$( cygpath 'C:\progs\sp5302-x64\perl\bin\perl.exe' )" -M5.010 -e'
   use Win32;
   BEGIN {
      Win32::SetConsoleCP(65001);
      Win32::SetConsoleOutputCP(65001);
   }
   use open ":std", ":encoding(UTF-8)";
   say chr(0x2660);
'
♠

BEGIN { `chcp 65001` } 也可以做到这一点。)

【讨论】:

    【解决方案2】:

    如果您在cmd.exe 窗口或PowerShell 中,您可以将代码页更改为65001:

    chcp 65001
    

    如果您不想更改代码页,请找出 chcp(或 "cp".Win32::GetConsoleOutputCP())返回的内容并编码为该编码。

    use Encode;
    
    open my $fh, '<:utf8','test.txt';
    while(<$fh>){
        print encode('cp850',$_); # needs a recent Encode to support cp850
    };
    close $fh;
    

    如果你在 cygwin bash 中,你可以像这样用system() 调用chcp

    use strict;
    use warnings;
    use Encode;
    
    system("chcp 65001 > NUL");
    
    open my $fh, '<:utf8','test.txt';
    while(<$fh>){   
        print encode('utf8',$_); # needs a recent Encode to support cp850
    };
    close $fh;
    

    【讨论】:

    • 感谢这个想法。 chcp 确实适用于 cmd。我仍在寻找 cygwin bash 的解决方案。在 Linux 机器上使用 bash 可以开箱即用,但在 Windows 上却不行。第二种解决方案将输出编码更改为 cp850,但只有少数 unicode 字符可以映射到 cp850。它适用于我上面示例中的变音符号,但我的真实脚本使用许多不同的字符。
    • 如果我在 bash 中调用 cmd /c chcp 65001,它也可以在 bash 中使用。这仍然看起来像一个丑陋的解决方法;-)
    【解决方案3】:

    您似乎缺少 LANG 设置

    $ export LANG=de_DE.UTF-8
    
    $ echo $LANG
    de_DE.UTF-8
    
    $ cat test.txt
    äöü
    
    $ perl test.pl
    äöü
    
    $ file test.txt
    test.txt: UTF-8 Unicode text
    
    $ od -c  test.txt
    0000000 303 244 303 266 303 274  \n
    0000007
    
    $ which perl
    /usr/bin/perl
    

    【讨论】:

    • 我已经试过了。执行您的命令后,我得到完全相同的输出 - 除了perl test.pl。太疯狂了。
    • 你用的是什么终端?你确定 perl 吗?
    • 我使用 Cygwin bash,但也尝试了“Windows Terminal”中的 bash,我尝试了“cmd.exe”和“Windows PowerShell”。我确定 perl 脚本的输出。 PC 本身只有几天的历史,并且没有任何非常特殊的软件进行设置。除此之外,我正在使用 Strawberry perl (strawberryperl.com)。
    • 不,我习惯使用 Strawberry,因为我可以轻松地在那里安装所有必需的软件包。我现在在 Linux 机器上尝试了我的脚本,它按预期工作。这可能不是 Perl 问题,而是 Windows 问题。另一方面: cat test.txt 有效...
    【解决方案4】:

    您可以明确定义输入和输出的编码。

    open( my $fh, '<:utf8', 'test.txt');
    binmode(STDOUT,':utf8');
    print <$fh>;
    close $fh;
    

    【讨论】:

    • 谢谢。我已经尝试过了,但没有成功。
    猜你喜欢
    • 1970-01-01
    • 2011-02-24
    • 2012-03-22
    • 2023-03-24
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 2014-11-04
    相关资源
    最近更新 更多