2011-05-06 2 views
6

У меня есть устаревшая программа, и после ее запуска он будет генерировать файл журнала. Теперь мне нужно проанализировать этот файл журнала.Как использовать perl для обработки файла, формат которого похож на unicode?

Но формат файла очень странный. Обратите внимание на следующее: я использовал vi, чтобы открыть его, он выглядит как файл unicode, но это не FFFE. после того, как я использовал блокнот, откройте его, сохраните его и снова откройте, я обнаружил, что FFFE добавлен в блокнот. Затем я могу использовать команду «тип log.txt> log1.txt», чтобы преобразовать весь файл в формат ANSI. Позже в perl я могу использовать/TDD/in 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. 
    } 
} 

Я прочитал нить, которая очень полезна, но все же не может разрешите мою проблему. How can I open a Unicode file with Perl?

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

Thanks Michael, Я пробовал ваш скрипт, но получил следующую ошибку. Я проверил мой 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. 

Update

Я попробовал 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, получил то же самое e rror.

Если бы я использовал UTF-16, я получил ошибку

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

open.pl линии 18

is "print while <$fh>;" 

Любая идея?

Обновлено: 05.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 ................ 
+0

Возможно, это поможет: http://www.perlmonks.org/?node_id=615796 –

+0

Вы пробовали указать различные кодировки для чтения потока? –

+0

Принятый ответ связанного с вами вопроса говорит вам, что именно вам нужно сделать, чтобы прочитать ваш кодированный файл UCS-2LE. Я просто попробовал, и это сработало для меня. - Более конкретно, по какой причине вы «не можете разрешить». – daxim

ответ

6

Ваш файл, кажется, закодированы в 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 
+0

Спасибо, Майкл. Я пробовал, но получил ошибку, как 'UTF-16: непризнанная спецификация 5400 на test.pl line 12'. строка на 'print <$fh>;' – Orionpax

+1

@Orionpax, в Perl, кодировка 'utf16' ожидает спецификацию, потому что она может быть большой или маленькой. Вместо этого попробуйте использовать 'UTF-16LE'. – cjm

+0

Затем вы запустили его в файле без спецификации. Переход к обновлению моего примера. – Lumi