perl - Perl中如何将一个值压入数组?
问题描述
我在将一些值插入哈希数组时遇到了问题,以获得整洁的屏幕打印。
文件输入
#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 );
我在放置原始日志文件时遇到了麻烦,因为我一插入它就被错误地处理了。
解决方案
有一些技巧可以使事情变得更简单。
更改输入记录分隔符,以便一次读取整个(多行)记录。用
$/
.一旦你有了多行记录,就把它分成几行。您可以按行的顺序知道各种事物的位置。
在处理每一行时输出结果。你不需要一个数据结构。
对于更复杂的事情,请查看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 具有后缀取消引用功能,这使它更漂亮:
$hash{'some_key'}->@*
使用它代替数组:
push $hash{'some_key'}->@*, 'newer value';
pop $hash{'some_key'}->@*;
推荐阅读
- html - 有没有办法在 YouTube iframe 上放置一个 div 标签以实现全屏显示?
- sql-server - pyodbc - 来自 Microsoft SQL Server 的图像以二进制模式写入错误
- javascript - 如何在 Swiper 中为中心幻灯片添加效果?
- java - Firebase Java 从 Firebase 存储中保存文件并知道外部存储器的保存路径
- java - 轮询函数Java Kafka Consumer出错
- java - 如果我在 JSP 中通过一种形式从两个 url 发送请求,我该怎么办?
- python - 如何将已经在终端上打印出来的字符转换为变量?
- selenium - C#:使用 Chrome 配置文件时无法并行运行硒测试
- keda - KEDA - redis listLength 如何缩放 pod(详细)
- linux - Long TTFB - Nginx 默认配置