Как вставить значение в массив в Perl? - PullRequest
0 голосов
/ 11 июня 2018

У меня проблема с вставкой некоторых значений в хеш-массив для аккуратной печати экрана.

Ввод файла

#2.#2018 05 24 10:43:38:683#+0200#Info#/Sys/Sec/Authentication#
#BC-JAS-SEC#security#C0000A7103EC9E50000000004#common.com/irj#com.common.services.security.authentication.logincontext.table#USER1#5##C47731E44D00000bae##0#Thread[HTTP
Worker [@1473726842],5,Dedicated_Application_Thread]#Plain## Login
User: USER1 IP Address: 127.0.0.1 Authentication Stack: ticket
Authentication Stack Properties:

#2.#2018 05 24 11:05:04:011#+0200#Info#/Sy/Sec/Authentication#
#BC-JAS-SEC#security#C0000A7103EC9F50000000004#common.com/irj#com.common.services.security.authentication.logincontext.table#USER4#6##A40B81404D03c0bae##0#Thread[HTTP
Worker [@1264376989],5,Dedicated_Application_Thread]#Plain## Login
User: USER4 IP Address: 127.0.0.1 Authentication Stack: ticket
Authentication Stack Properties:

#2.#2018 05 24 11:05:07:100#+0200#Info#/Sys/Sec/Authentication#
#BC-JAS-SEC#security#C0000A7103ECA0C#3935150000000004#common.com/irj#com.common.services.security.authentication.logincontext.table#USER3#7##9ACF7Ec0bae##0#Thread[HTTP
Worker [@124054179],5,Dedicated_Application_Thread]#Plain## Logout
User: USER3 IP Address: 127.0.0.1 Authentication Stack: ticket
Authentication Stack Properties:

#2.#2018 05 24 11:07:21:314#+0200#Warn#/Sys/Sec/Authentication#
#BC-JAS-SEC#security#C0000A7103ECA20E0000508C#3935150000000004#common.com/irj#com.common.services.security.authentication.logincontext.table#USER2#03c0bae##0#Thread[HTTP
Worker [@2033389552],5,Dedicated_Application_Thread]#Plain## Login
User: USER2 IP Address: 127.0.0.1 Authentication Stack: ticket
Authentication Stack Properties:

#2.#2018 05 02 10:48:05:700#+0200#Warn#/Sys/Sec/Authentication#
#BC-JAS-SEC#security#C0000A7103ECA20050000508C#3935150000000004#common.com/irj#com.common.services.security.authentication.logincontext.table#USER2#0##E0E##0#Thread[HTTP
Worker [@2033389552],5,Dedicated_Application_Thread]#Plain## Logout
User: USER2 IP Address: 127.0.0.1 Authentication Stack: ticket

Требуемый вывод

Date;Time;Type;User
2018/05/24;10:43:38:683;Login;USER1
2018/05/24;11:05:04:011;Login;USER4
2018/05/24;11:05:07:100;Logout;USER3
2018/05/24;11:07:21:314;Login;USER2

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 );

У меня проблемы с переносом исходного файла журнала, потому что, как только я его вставляю, он неправильно обрабатывается.

Ссылкаэто mylog.txt файл

1 Ответ

0 голосов
/ 11 июня 2018

Существуют некоторые приемы, которые могут значительно упростить процесс.

  • Измените разделитель входных записей, чтобы вы сразу читали целые (многострочные) записи.Сделайте это с помощью $/.

  • Получив многострочную запись, разбейте ее на строки.Вы знаете положение различных вещей в порядке строк.

  • Выведите результат при обработке каждой строки.Для этого вам не нужна структура данных.

  • Для более сложных вещей посмотрите на 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 , которая делает это немного красивее:

$hash{'some_key'}->@*

Используйте это вместо массива:

push $hash{'some_key'}->@*, 'newer value';
pop $hash{'some_key'}->@*;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...