如何使用perl处理格式类似于unicode的文件



我有一个遗留程序,在运行它之后,它将生成一个日志文件。现在我需要分析这个日志文件。

但是文件格式很奇怪。请看下面,我用vi打开它,它看起来像一个unicode文件,但它不是FFFE启动。我用记事本打开,保存,再打开,我发现FFFE是用记事本添加的。然后我可以使用命令"type log.txt> log1.txt"将整个文件转换为ANSI格式。稍后在perl中,我可以使用/TDD/在perl中搜索我需要的内容。

但是现在,我无法处理这种文件格式。

任何评论或想法将非常感谢。

0000000: 5400 4400 4400 3e00 2000 4c00 6f00 6100  T.D.D.>. .L.o.a.

记事本后保存

0000000: fffe 5400 4400 4400 3e00 2000 4c00 6f00  ..T.D.D.>. .L.o.
open STDIN, "< log.txt";
while(<>)
{
  if (/TDD/)
  {
    # Add my logic.
  }
}

我已经读了这是非常有用的线程,但仍然不能解决我的问题。如何用Perl打开Unicode文件?

我不能添加答案,所以我编辑了我的帖子。

谢谢迈克尔,我尝试了你的脚本,但得到了以下错误。我检查了我的perl版本是5.1,操作系统是windows 2008。

* ascii
* ascii-ctrl
* iso-8859-1
* null
* utf-8-strict
* utf8
UTF-16:Unrecognised BOM 5400 at test.pl line 12.

我用命令

尝试了UTF-16LE
perl.exe open.pl utf-16le utf-16 <my log file>.txt

但是我还是得到了像

这样的错误
UTF-16LE:Partial character at open.pl line 18, <$fh> line 1824.

也,我尝试了utf-16be,得到了同样的错误。

如果我使用utf-16,我将得到错误

UTF-16:Unrecognised BOM 5400 at open.pl line 18.

open.pl line 18

is "print while <$fh>;"

任何想法?

更新:5/11/2011。谢谢你们的帮助。我解决了这个问题。我发现日志文件中的数据毕竟不是UTF-16。所以,我不得不用visual studio编写一个。net项目。它将使用UTF-16读取日志文件,并使用UTF-8写入新文件。然后使用perl脚本对文件进行解析并生成结果数据。现在起作用了。

所以,如果你们中有人知道如何使用perl读取一个有很多垃圾数据的文件,请告诉我,非常感谢。

。垃圾数据样本

tests.cpp:34)
਍吀䐀䐀㸀 䰀漀愀搀椀渀最 挀挀洀挀漀爀攀⸀搀氀

使用十六进制阅读器打开它:

0000070: a88d e590 80e4 9080 e490 80e3 b880 e280  ................
0000080: 80e4 b080 e6bc 80e6 8480 e690 80e6 a480  ................
0000090: e6b8 80e6 9c80 e280 80e6 8c80 e68c 80e6  ................
00000a0: b480 e68c 80e6 bc80 e788 80e6 9480 e2b8  ................

您的文件似乎是以UTF-16LE编码的。记事本添加的字节称为"字节顺序标记",或简称为BOM。

下面是如何使用Perl读取文件:
use strict;
use warnings;
use Encode;
# list loaded encodings
print STDERR map "* $_n", Encode->encodings;
# read arguments
my $enc = shift || 'utf16';
die "no files :-(n" unless @ARGV;
# process files
for ( @ARGV ) {
    open my $fh, "<:encoding($enc)", $_ or die "open $_: $!";
    print <$fh>;
    close $fh;
}
# loaded more encodings now
print STDERR map "* $_n", Encode->encodings;

像这样继续,注意为您的文件提供正确的编码:

perl open.pl utf16 open.utf16be.txt
perl open.pl utf16 open.utf16le.txt
perl open.pl utf16le open.utf16le.nobom.txt

以下是根据基督的建议修改的版本:

use strict;
use warnings;
use Encode;
# read arguments
my $enc_in  = shift || die 'pass file encoding as first parameter';
my $enc_out = shift || die 'pass STDOUT encoding as second parameter';
print STDERR "going to read files as encoded in: $enc_inn";
print STDERR "going to write to standard output in: $enc_outn";
die "no files :-(n" unless @ARGV;
binmode STDOUT, ":encoding($enc_out)"; # latin1, cp1252, utf8, UTF-8
print STDERR map "* $_n", Encode->encodings; # list loaded encodings
for ( @ARGV ) { # process files
    open my $fh, "<:encoding($enc_in)", $_ or die "open $_: $!";
    print while <$fh>;
    close $fh;
}
print STDERR map "* $_n", Encode->encodings; # more encodings now

相关内容

  • 没有找到相关文章

最新更新