在Windows perl中使用BOM和Unix行结束流处理UTF-16文件

时间:2012-02-25 20:13:21

标签: perl unicode utf-16

我需要使用perl以UTF-16 little-endian编码的1Gb文本文件进行流处理,其中包含unix样式的结尾(即流中只有0x000A而没有0x000D)和LE BOM。文件在Windows上处理(也需要Unix解决方案)。通过流处理,我的意思是使用while(<>),逐行读取和写入。 很高兴有一个命令行单行,如: perl -pe“BEGIN {SOME_PREPARATION}; s / SRC / DST / g;” infile.txt> outfile.txt

用于测试的输入的十六进制转储(两行:每行上的“a”和“b”字母): FF FE 61 00 0A 00 62 00 0A 00

s / b / c / g 这样的处理应该给出一个输出(“b”替换为“c”): FF FE 61 00 0A 00 63 00 0A 00

PS。现在我的所有试验都是CRLF输出有问题(输出0D 0A字节产生不正确的unicode符号,我只需要0A00而没有0D00来保留相同的unix风格)或者每个新行都切换LE / BE,即相同的“a” “在一行上,奇数行为6100,输出为偶数行为0061。

1 个答案:

答案 0 :(得分:3)

我想出的最好的是:

perl -pe "BEGIN { binmode $_, ':raw:encoding(UTF-16LE)' for *STDIN, *STDOUT }; s/b/c/g;" <infile.txt >outfile.txt

但请注意,我必须使用<infile.txt而不是infile.txt,以便文件位于STDIN上。从理论上讲,open编译指示应该控制魔术ARGV文件句柄所使用的编码,但在这种情况下我无法使其正常工作。

<infile.txtinfile.txt之间的区别在于文件的打开方式和时间。使用<infile.txt,文件连接到标准输入,并在Perl开始运行之前打开。当您在binmode STDIN块中BEGIN时,该文件已经打开,您可以更改编码。

使用infile.txt时,文件名作为命令行参数传递并放在@ARGV数组中。执行BEGIN块时,文件尚未打开,因此您无法设置其编码。从理论上讲,你应该能够说:

use open qw(:std IO :raw:encoding(UTF-16LE));

并使魔术<ARGV>处理应用正确的编码。但在这种情况下,我无法让它正常工作。