我有一个问题是将一些值插入到哈希数组中,以便进行整洁的屏幕打印。
#!/usr/bin/perl
use strict;
use warnings 'all';
use feature qw(say);
my $path = "mylog.txt";
open( FILE, $path ) or die $!;
my @array;
my $i = 0;
my %csv = ( l_d => 'Date', l_t => 'Time', l_msg => 'Type', l_usr => 'User', cr => '\n', );
while ( @array = <FILE> ) {
foreach my $line ( @array ) {
if ( $line =~ m/^#\d.\d.#\d{4}\s\d{2}\s\d{2}\s\d{2}:\d{2}:\d{2}:\d{3}#\+\d+#\w+#\/\w+\/\w+\/Authentication/ ) {
if ( $array[ $i + 2 ] =~ m/Login/ || $array[ $i + 2 ] =~ m/Logout/ && $array[ $i + 3 ] !~ m/NOUSER/ ) {
my $l_d = substr( $line, 6, 10 );
$l_d =~ s/\s/\//g;
my $l_t = substr( $line, 17, 12 );
my $l_msg = substr( $array[ $i + 2 ], 0, -1 );
my $l_usr = substr( $array[ $i + 3 ], 6 );
print "Date: $l_d\n";
print "Time: $l_t\n";
print "Type: $l_msg\n";
print "User: $l_usr\n";
# I would push these value into %csv('*')
#push @{ %csv->{l_d}->[$l_d] }, $l_d; # I would push into %csv('l_d') the $l_d value
#push @{ %csv->{l_t}->[$l_t] }, $l_t; # I would push into %csv('l_t') the $l_t value
#push @{ %csv->{l_msg}->[$l_msg] }, $l_msg; # I would push into %csv('l_msg') the $l_t value
#push @{ %csv->{l_usr}->[$l_usr] }, $ld_usr;# I would push into %csv('l_usr') the $l_t value
# End of loop
}
}
$i++;
}
}
close( FILE );
print "Csv Example:\n\n";
print "$csv{'l_d'};$csv{'l_t'};$csv{'l_msg'};$csv{'l_usr'}\n";
#open my $filecsv, '>', 'outfile.csv' or die $!;
#$csv->print( $filecsv, \%csv );
{{1}}
{{1}}
我无法放入原始日志文件,因为一旦插入它就会被错误处理。
答案 0 :(得分:5)
有一些技巧可以使事情变得更简单。
更改输入记录分隔符,以便一次读取整个(多行)记录。使用$/
。
获得多行记录后,将其分成几行。你知道各种事物的排列顺序。
在处理每一行时输出结果。您不需要数据结构。
对于更复杂的事情,请查看Text::CSV_XS以处理逗号分隔值文件的复杂性。
$/ = "\n\n"; # record separator
while( <FILE> ) {
chomp;
my @lines = split /\n/;
my ($y, $m, $d, $time ) =
$lines[0] =~ /\A\#\d+\.\#(\d+)\s+(\d+)\s+(\d+)\s+([^#]+)/;
my $action = $lines[-2];
my $user = (split /\s+/, $lines[-1])[-1];
say join ';',
"$y/$m/$d",
$time,
$action,
$user
}
但是,现在让我们回答可能带来人们的名义问题。您希望将数组存储为哈希值。这很简单。数组引用(实际上,所有引用)都是标量。您可以使用标量执行相同的操作,包括将它们用作哈希值:
my @array = ( ... );
my %hash;
$hash{'some_key'} = \@array; # take a reference to a named array
但您不需要命名数组。 [ ]
直接创建数组引用:
$hash{'some_key'} = [ ... ]; # anonymous array constructor
现在您将此数组引用值作为您的哈希键,并且您希望使用它来执行数组操作。首先,你需要取消引用它。将返回数组引用的东西放在@{ }
:
@{ $hash{'some_key'} }
在您使用指定数组的任何地方使用它:
push @{ $hash{'some_key'} }, 'new value';
pop @{ $hash{'some_key'} };
Perl v5.24的postfix dereferencing feature使它更漂亮:
$hash{'some_key'}->@*
用它代替数组:
push $hash{'some_key'}->@*, 'newer value';
pop $hash{'some_key'}->@*;