【问题标题】:Process text as utf-16 via perl one-liner?通过 perl one-liner 将文本处理为 utf-16?
【发布时间】:2015-03-03 05:02:07
【问题描述】:

perl 有一个选项perl -C 来处理 utf-8,是否可以单线告诉 perl 输入是 utf-16 编码? BEGIN 块可能用于显式更改编码,还有更简单的方法吗?

【问题讨论】:

  • use open .... 或者 perlrun 中的 -M 标志怎么样?
  • @tjd 我想知道你的完整解决方案:)
  • 在 Windows 上,你真的不能这样做,因为 :crlf 和 :encoding 会以错误的顺序结束。
  • @ikegami 很有趣。为什么 :crlf 和 :encoding 的顺序仅在 Windows 上是错误的?
  • :crlf 仅在 Windows 上添加。如果添加了其他构建:crlf,那么他们也会遇到问题。

标签: perl unicode


【解决方案1】:

Encode 可以做你想做的事吗?然后,您可能必须在脚本中使用 encode()decode(),因此它可能不会短于:

    perl -nE 'BEGIN {binmode STDIN, ":encoding(utf16)" } ; ...'

有一个PERL_UNICODE 环境变量,但它相当有限:如果我没记错的话,它只是模仿-C

我曾经试图找出为什么没有-C 用于“流行” UTF 形式的开关,这似乎归结为它们是否经常使用;是否被很好理解(字节序有时很重要——谁知道?);已经过时或应该过时; ... :换句话说,它并不像看起来那么简单。

c.f. @Leon Timmerman 的例子和相当彻底的 perldoc open

% perl -Mopen=":std,:encoding(utf-16)" -E 'print <>' UTF16.txt > other.txt
% file other.txt 
other.txt: Big-endian UTF-16 Unicode text, with CRLF line terminators


编辑: 最近另一个关于如何"Turn Off" binmode(STDOUT, ":utf8") Locally 的讨论涉及 PerlIO 和“层”,并且有一个简洁的解决方案,可能适合单行。参见UTF-16 perl input output

我将尝试找到一个使用Encode 的真实示例来保留可以单行的编码。它会像这样“往返”。 例如

% file UTF16.txt
UTF16.txt: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators

... 吞下它并将其重定向到不同的文件:

% perl -00 -MEncode="encode,decode"  -E '
  $text = decode("UTF-16LE", <>) ;  
  print encode("UTF-16LE", $text)' UTF16.txt > other.txt
% file other.txt
other.txt: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators

diff 并以字节为单位打印文件的大小:

% diff UTF16.txt other.txt
% perl -E 'say [stat]->[7] for @ARGV' UTF16.txt other.txt
2220
2220 

【讨论】:

  • 我在 Windows 上使用 Perl 5.14 运行了你的最后一个命令,针对一个 utf-16 文件,Windows 中的许多本机应用程序都可以查看该文件,例如 typenotepad,但 perl 抱怨“UTF -16:无法识别的 BOM 7061"
  • 我不熟悉 Windows 上的 perl 如何与各种 PerlIO 层交互,但perlrun 描述了许多选项(:crlf ) - a解决方案可能就在那里。在您的情况下,文本可能是BOM-ed(标记字节顺序)并且需要小端/大端编码?
  • 如果操作系统/软件供应商和 Unicode 联盟还没有提供一个真正易于使用的健壮标准,那可能是因为语言和书写系统并不易于使用、编码、解码、存储很长一段时间,翻译,......甚至在纸上。
  • @Thomson 在处理 Unicode、IO、层、:bytes:crlf 时,很难制作适用于 Windows 和 Unix/Linux/BSD/Solaris/OSX 系列的“便携式”单行。现在我也有疑问。
  • perlmonks.org/?node_id=986776 展示了如何删除 BOM 以“取消标记”UTF-16LE 编码的文档。做备份听起来很可怕。
【解决方案2】:

你可以使用perl -Mopen=":std,IN,:encoding(utf-16)" -e '...'来做到这一点

【讨论】:

  • 这个在 Windows 上运行良好。我认为IN 是必要的,也是这里的关键。你能多解释一下这个语法吗?
猜你喜欢
  • 2014-07-31
  • 2014-05-08
  • 1970-01-01
  • 2016-11-22
  • 2017-06-04
  • 2015-08-19
  • 2014-03-19
  • 2013-09-02
  • 2012-08-01
相关资源
最近更新 更多