Я новичок в perl и не очень хорошо разбираюсь в структурах данных. Я работал над текстовым анализатором, чтобы извлечь информацию из текстового файла и сохранить его в базе данных. Регулярные шаблоны теперь одобрены, но я только заметил, что ключ, который я использовал для моего хэша «Время» не уникален, так как в нем есть несколько обновлений (в текстовом файле), которые могут произойти одновременно. То, что делает хэш, создает дубликаты, неприемлемые для моей цели. Поэтому я думал добавить еще один ключ, возможно, уникальный счетчик, но я не знаю, как это сделать. Таким образом, я пытался добавить еще один ключевой «{$ recordcnt}» в качестве счетчика вы увидите, что добавляется на всех хэш statements.I удаляемого операторы счетчика приращения (возможно я не правильно реализовать)Perl Parser using Hash
Кроме того, если вы посмотрите на блок оператора печати (последний раздел) моего кода, я пытаюсь распечатать, получить массив (@nodes_and_index) значение, которое содержит два столбца узлов и индекса, печатать и отображать их по-разному. Однако он не печатает желаемые результаты. Было тестирование, предполагая, что я хотел бы вводить данные в базу данных отдельно.
Итак, я поставил «{$ recordcnt}» в неправильных местах, если это так. Как сделать каждую запись уникальной в хэш со временем? Спасибо за прочтение.
Это пример моих данных:
TIME: 11/01/13 14:30:24
FROM: 10.255.9.4 AS172193
TO: 10.255.9.10 AS676767
ASPATH: 172193 19601 14835 1286 577 4097 2841 14735 9486 573 10633 4488
NEXT_HOP: 10.255.9.126
ANNOUNCE
10.44.193.0/24
TIME: 11/01/13 14:30:24
FROM: 10.255.9.4 AS172193
TO: 10.255.9.10 AS676767
ASPATH: 172193 19601 14835 4758 2379 10721 10787 7830 17777 4875 4488
NEXT_HOP: 10.255.9.126
ANNOUNCE
10.44.193.0/24
TIME: 11/01/13 14:30:25
FROM: 10.255.9.4 AS172193
TO: 10.255.9.10 AS676767
ASPATH: 172193 19601 14835 4758 2379 10721 10787 7830 17777 16480 9486 573 10633 4488
NEXT_HOP: 10.255.9.126
ANNOUNCE
10.44.193.0/24
TIME: 11/01/13 14:30:25
FROM: 10.255.9.4 AS172193
TO: 10.255.9.10 AS676767
ASPATH: 172193 19601 19602 3252 3665 2315 2379 10721 7311 12934 4875 4488
NEXT_HOP: 10.255.9.125
ANNOUNCE
10.44.193.0/24
TIME: 11/01/13 14:30:34
FROM: 10.255.9.4 AS172193
TO: 10.255.9.10 AS676767
ASPATH: 172193 19601 19602 3252 3665 2315 2379 3725
NEXT_HOP: 10.255.9.125
ANNOUNCE
10.44.193.0/24
Это мой полный код:
#!/usr/bin/perl -w
use strict;
use warnings;
my %hash;
my $Dir = "/root/updates/processed/";
my $exit = 0;
my $recordcnt = 0 ;
opendir(DIRECTORY, $Dir) or die $!;
while (my $file = readdir(DIRECTORY)) {
unless ($file=~/\.hr$/){next;}
my $file = $Dir."/".$file;
print "$file\n";
open (IN, $file) or die "error reading file: ", $file,"\n";
my $record_id = "";
#my $recordcnt = 0 ;
my $type = "";
my $peer_ip = "";
my $peer_as = "";
my $local_ip = "";
my $local_as = "";
my $next_hop = "";
my @nodes_and_index =();
my @withdraw_prefix =();
my @announce_prefix =();
while (<IN>) {
#$exit++; last if ($exit==5);
if (/^TIME/) {
if ($type) {$hash{$record_id}{$recordcnt}{'type'} = $type;}
if ($peer_ip) {$hash{$record_id}{$recordcnt}{'peer_ip'} = $peer_ip;}
if ($peer_as) {$hash{$record_id}{$recordcnt}{'peer_as'} = $peer_as;}
if ($local_ip) {$hash{$record_id}{$recordcnt}{'local_ip'} = $local_ip;}
if ($local_as) {$hash{$record_id}{$recordcnt}{'local_as'} = $local_as;}
if ($next_hop) {$hash{$record_id}{$recordcnt}{'next_hop'} = $next_hop;}
if (@nodes_and_index) {push @{$hash{$record_id}{$recordcnt}{'nodes_and_index'}}, @nodes_and_index;}
if (@withdraw_prefix) {push @{$hash{$record_id}{$recordcnt}{'withdraw_prefix'}}, @withdraw_prefix;}
if (@announce_prefix) {push @{$hash{$record_id}{$recordcnt}{'announce_prefix'}}, @announce_prefix;}
$peer_as = "";
$peer_ip = "";
$type = "";
$local_ip = "";
$local_as = "";
$next_hop = "";
$record_id = "";
$recordcnt = 0;
@nodes_and_index =();
@withdraw_prefix =();
@announce_prefix =();
my @time = split '\s', $_;
$record_id = $time[1]."_".$time[2];
} elsif (/^FROM/) {
my @from_tmp = split '\s', $_;
$peer_ip = $from_tmp[1];
$peer_as = $from_tmp[2];
$peer_as =~ s/AS//;
} elsif (/^TO/) {
my @to_tmp = split '\s', $_;
$local_ip = $to_tmp[1];
$local_as = $to_tmp[2];
$local_as =~ s/AS//;
#print "$local_ip\n";
} elsif (/^ASPATH/) {
my @nodes_tmp = split '\s', $_;
shift @nodes_tmp;
my $index = 0;
foreach my $node (@nodes_tmp) {
$index++;
push @nodes_and_index, ($node , $index);
}
}elsif (/^NEXT_HOP/) {
my @next_hop_tmp = split '\s', $_;
$next_hop = $next_hop_tmp[1];
}elsif (/^WITHDRAW/) {
while (<IN>) {
last if !/^ +/;
@withdraw_prefix, $_ ;
}
}elsif (/^ANNOUNCE/) {
while (<IN>) {
last if !/^ +/;
push @announce_prefix, $_;
}
}
if ($record_id) { # handle last result
$hash{$record_id}{$recordcnt}{'peer_as'} = $peer_as;
$hash{$record_id}{$recordcnt}{'peer_ip'} = $peer_ip;
$hash{$record_id}{$recordcnt}{'local_as'} = $local_as;
$hash{$record_id}{$recordcnt}{'local_ip'} = $local_ip;
$hash{$record_id}{$recordcnt}{'next_hop'} = $next_hop;
push @{$hash{$record_id}{$recordcnt}{'nodes_and_index'}} ,@nodes_and_index;
push @{$hash{$record_id}{$recordcnt}{'withdraw_prefix'}} ,@withdraw_prefix;
push @{$hash{$record_id}{$recordcnt}{'announce_prefix'}} ,@announce_prefix;
}
}
close IN;
}
my @arraystuff;
my @separated;
my @iindex=();
my @ppath=();
foreach (sort keys %hash) {
print $_, "\n";
print "\t $hash{$_}{$recordcnt}{'peer_ip'}\n";
print "\t $hash{$_}{$recordcnt}{'peer_as'}\n";
print "\t $hash{$_}{$recordcnt}{'local_ip'}\n";
print "\t $hash{$_}{$recordcnt}{'local_as'}\n";
print "\t $hash{$_}{$recordcnt}{'next_hop'}\n";
@arraystuff = @{$hash{$_}{$recordcnt}{'nodes_and_index'}};
foreach (@arraystuff) {
@separated = split('\s', $_);
push @iindex, $separated[1];
push @ppath, $separated[0];
print "\t index: @iindex";
print "\t path: @ppath";
}
print "\t node index : @{$hash{$_}{$recordcnt}{'nodes_and_index'}}\n";
print "\t withdraw_prefix: @{$hash{$_}{$recordcnt}{'withdraw_prefix'}}\n";
print "\t announce: @{$hash{$_}{$recordcnt}{'announce_prefix'}}\n";
}
============== ================================================== ===================================
Новая версия, рекомендованная Foibs
#!/usr/bin/perl -w
use strict;
use warnings;
my @datasetarray;
my $Dir = "/root/updates\/processed/";
my $exit = 0;
opendir(DIRECTORY, $Dir) or die $!;
while (my $file = readdir(DIRECTORY)) {
unless ($file=~/\.hr$/){next;}
#unless ($file=~/\.txt$/){next;}
my $file = $Dir."/".$file;
print "$file\n";
open (IN, $file) or die "error reading file: ", $file,"\n";
my $record_id = "";
my $type = "";
my $peer_ip = "";
my $peer_as = "";
my $local_ip = "";
my $local_as = "";
my $next_hop = "";
my @nodes_and_index =();
my @withdraw_prefix =();
my @announce_prefix =();
my $tmphash = {};
while (<IN>) {
#$exit++; last if ($exit==5);
if (/^TIME/) {
if ($type) {$tmphash->{'type'} = $type;}
if ($peer_ip) {$tmphash->{'peer_ip'} = $peer_ip;}
if ($peer_as) {$tmphash->{'peer_as'} = $peer_as;}
if ($local_ip) {$tmphash->{'local_ip'} = $local_ip;}
if ($local_as) {$tmphash->{'local_as'} = $local_as;}
if ($next_hop) {$tmphash->{'next_hop'} = $next_hop;}
#if (@nodes_and_index) {push {$tmphash->{'nodes_and_index'}}, @nodes_and_index;}
#if (@withdraw_prefix) {push {$tmphash->{'withdraw_prefix'}}, @withdraw_prefix;}
#if (@announce_prefix) {push {$tmphash->{'announce_prefix'}}, @announce_prefix;}
#The three commented lines above provide error, thus i don't know if i am implementing it the right way, since they are array and different from the others.
$peer_as = "";
$peer_ip = "";
$type = "";
$local_ip = "";
$local_as = "";
$next_hop = "";
$record_id = "";
@nodes_and_index =();
@withdraw_prefix =();
@announce_prefix =();
my @time = split '\s', $_;
$record_id = $time[1]."_".$time[2];
} elsif (/^TYPE/) {
my @type_tmp = split '\s', $_;
$type = $type_tmp[1];
} elsif (/^FROM/) {
my @from_tmp = split '\s', $_;
$peer_ip = $from_tmp[1];
$peer_as = $from_tmp[2];
$peer_as =~ s/AS//;
} elsif (/^TO/) {
my @to_tmp = split '\s', $_;
$local_ip = $to_tmp[1];
$local_as = $to_tmp[2];
$local_as =~ s/AS//;
} elsif (/^ASPATH/) {
my @nodes_tmp = split '\s', $_;
shift @nodes_tmp;
my $index = 0;
foreach my $node (@nodes_tmp) {
$index++;
push @nodes_and_index, ($node , $index);
}
}elsif (/^NEXT_HOP/) {
my @next_hop_tmp = split '\s', $_;
$next_hop = $next_hop_tmp[1];
}elsif (/^WITHDRAW/) {
while (<IN>) {
last if !/^ +/;
push @withdraw_prefix, $_ ;
}
}elsif (/^ANNOUNCE/) {
while (<IN>) {
last if !/^ +/;
push @announce_prefix, $_;
}
}
if ($record_id) { # handle last result
push @datasetarray, $tmphash;
$tmphash = {};
}
}
close IN;
}
foreach my $row (@datasetarray) {
print $_, "\n"; #Time doesn't get printed
print "\t $row->{'peer_ip'}\n"; #OK
print "\t $row->{'peer_as'}\n"; #OK
print "\t $row->{'local_ip'}\n"; #OK
print "\t $row->{'local_as'}\n"; #OK
print "\t $row->{'next_hop'}\n"; #OK
# print "\t $row->{'nodes_and_index'}\n"; # Are these guys ok ? since they are arrays
# print "\t $row->{'withdraw_prefix'}\n"; # Are these guys ok ? since they are arrays
# print "\t $row->{'announce_prefix'}\n"; # Are these guys ok ? since they are arrays
}
Благодарим вас за ответ и даю мне 2 варианта, которые я действительно ценю. Я хотел бы попробовать первый вариант, добавив recordcnt в record_id, как вы предложили. Пожалуйста, где я должен инициализировать и увеличивать его? Основываясь на результатах этого, я решит пойти с вариантом 2, который лучше, чем вы советовали :) –
* Теперь у меня есть счетчик, который работает как ожидалось. Но я получаю дублированные значения, например: * ** ASPATH: 172193 1 19601 2 14835 3 4758 4 2379 5 172193 1 19601 2 14835 3 4758 4 2379 5 172193 1 19601 2 14835 3 4758 4 2379 5 ** * Результаты потому что это повторяется 3 раза, я не знаю почему. * –
Поскольку вы используете этот 'if (/^TIME /) {' блок, чтобы отличать новые записи, вы должны увеличивать $ recordcnt внутри блока 'if'. Прямо сейчас вы устанавливаете его равным 0, если это неверно. Вы уже инициализируете его корректно за пределами всех циклов while. – foibs