Более расколотая версия, основанная на ответе leonbloy . Прямое разделение не будет работать из-за нечетного количества элементов. Поэтому вместо этого мы явно разделяем на =
и допускаем, чтобы пустые значения были неопределенными, чтобы сохранить пары ключ / значение хеш-функции.
Код:
use strict;
use warnings;
my $str1="ssh_2-4^accept IN=ETH2 OUT=eth33 MAC=00:d0:c9:96:62:c0:00:1c:f0:98:19:57:08:00 SRC=192.168.200.30 DST=192.168.200.224 LEN=48 TOS=0x00 PREC=0x00 TTL=128 ID=30546 DF PROTO=TCP SPT=10159 DPT=4319 WINDOW=7300 RES=0x00 SYN URGP=0";
my $str2="ssh_2-4^accept IN=ETH2 OUT=eth33 MAC=00:d0:c9:96:62:c0:00:1c:f0:98:19:57:08:00 SRC=192.168.200.30 DST=192.168.200.224 LEN=48 TOS=0x00 PREC=0x00 TTL=128 ID=30546 DF PROTO=ICMP WINDOW=7300 RES=0x00 URGP=0";
my @data;
for my $str ($str1, $str2) {
my %hash;
# First we extract the "header"
$str =~ s/^([^^]+)\^(\w+) // || die "Did not match header";
$hash{'version'} = $1;
$hash{'action'} = $2;
# Now process the args
for my $line (split ' ', $str) {
my ($key, $val) = split /=/, $line;
$hash{$key} = $val;
}
# Save the hash into an array
push @data, \%hash;
}
for my $href (@data) {
# Now output the selected elements from each hash
my $out = join ", ",
@$href{'version','action','IN','OUT','SRC','DST','PROTO'};
if ($href->{'PROTO'} eq 'TCP') {
$out = join ", ", $out, @$href{'SPT', 'DPT'};
}
print "$out\n";
}
Выход:
ssh_2-4, accept, ETH2, eth33, 192.168.200.30, 192.168.200.224, TCP, 10159, 4319
ssh_2-4, accept, ETH2, eth33, 192.168.200.30, 192.168.200.224, ICMP