我需要使用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 00PS。现在我的所有试验都是CRLF输出有问题(输出0D 0A字节产生不正确的unicode符号,我只需要0A00而没有0D00来保留相同的unix风格)或者每个新行都切换LE / BE,即相同的“a” “在一行上,奇数行为6100,输出为偶数行为0061。
答案 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.txt
和infile.txt
之间的区别在于文件的打开方式和时间。使用<infile.txt
,文件连接到标准输入,并在Perl开始运行之前打开。当您在binmode STDIN
块中BEGIN
时,该文件已经打开,您可以更改编码。
使用infile.txt
时,文件名作为命令行参数传递并放在@ARGV
数组中。执行BEGIN
块时,文件尚未打开,因此您无法设置其编码。从理论上讲,你应该能够说:
use open qw(:std IO :raw:encoding(UTF-16LE));
并使魔术<ARGV>
处理应用正确的编码。但在这种情况下,我无法让它正常工作。