Как использовать Perl для обработки файла, формат которого похож на Unicode? - PullRequest
6 голосов
/ 06 мая 2011

У меня есть устаревшая программа, и после ее запуска она сгенерирует файл журнала.Теперь мне нужно проанализировать этот файл журнала.

Но формат файла очень странный.Пожалуйста, посмотрите следующее, я использовал 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.
  }
}

У меня естьпрочитайте ветку, которая очень полезна, но все еще не может решить мою проблему. Как я могу открыть файл Unicode с помощью Perl?

Я не могу добавить ответ, поэтому я редактирую свойнить.

Спасибо, Майкл, я попробовал ваш скрипт, но получил следующую ошибку: Я проверил, что моя версия 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 строка 18

is "print while <$fh>;"

Есть идеи?

Обновлено: 5/11 /2011.Спасибо, ребята, за вашу помощь.Я решил проблему.Я обнаружил, что данные в лог-файле не являются UTF-16 в конце концов.Итак, мне пришлось написать .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  ................

1 Ответ

6 голосов
/ 06 мая 2011

Ваш файл, кажется, закодирован в UTF-16LE. Добавляемый блокнот байтов называется «Порядок следования байтов» или просто спецификацией.

Вот как вы можете прочитать свой файл, используя 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

Вот пересмотренная версия после предложений tchrist:

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_in\n";
print STDERR "going to write to standard output in: $enc_out\n";
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
...