如何将值推入Perl中的数组?

时间:2018-06-11 12:54:54

标签: perl

我有一个问题是将一些值插入到哈希数组中,以便进行整洁的屏幕打印。

文件输入

#!/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}}

的Perl

{{1}}

我无法放入原始日志文件,因为一旦插入它就会被错误处理。

Collection<T>

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'}->@*;