Perl数组不保存所有变量
我有一个Perl程序,它解析外部程序中的数据并将其保存到数组中。但是,有些数据未保存,稍后尝试恢复时会返回空白。Perl数组不保存所有变量
下面的代码解析的数据,这些数据来自通过为@packetData
:
if(@packetData[0] ne ""){
if(!$detectedClient{"@packetData[0]"}) {
my $rawSignal = average(@packetData[2]);
my $distance = 10**((27.55-(20*logten(2437))+abs($rawSignal))/20);
my @newClient = ($rawSignal, # Signal (dBm)
1, # Count
@packetData[0], # Source MAC
time(), # Last seen
$distance); # Distance (m)
$detectedClient{"@packetData[0]"} = [@newClient];
$uniqueClient++;
print "++ New probe request from @packetData[0] [$rawSignal dBm, $distance m]\n";
} else {
$detectedClient{"@packetData[0]"}[1]++;
$detectedClient{"@packetData[0]"}[3] = time();
}
}
的print
声明显示信号和距离的罚款,但试图从detectedClient
阵列显示它给出了下面的代码给出了一个空白处:
for $key2 (keys %detectedClient) {
#Signal, Count, MAC, Time
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($detectedClient{$key2}[3]);
my $lastSeen = sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
print STDOUT sprintf("!! %-20s %10s %-20s\n", $detectedClient{$key2}[2], $detectedClient{$key2}[1], $lastSeen, $detectedClient{$key2}[0], $detectedClient{$key2}[4]);
}
任何想法为什么会发生这种情况?
信号和距离不打印,因为你的模式("!! %-20s %10s %-20s\n"
)没有引用它们(第4和第5的值)。修复:
printf("!! %-20s %5s %-20s %20s %20s\n",
$detectedClient{$key2}[2],
$detectedClient{$key2}[1],
$lastSeen,
$detectedClient{$key2}[0],
$detectedClient{$key2}[4],
);
测试使用下列内容:(后来换for $key2
到for my $key2
太)
use strict;
use warnings qw(all);
use List::Util qw(sum);
sub average { sum(@{ $_[0] })/@{ $_[0] } }
sub logten { log($_[0])/log(10) }
my @packetData = ("foo", undef, [ 4, 5 ]);
my %detectedClient;
my $uniqueClient;
if(@packetData[0] ne ""){
if(!$detectedClient{"@packetData[0]"}) {
my $rawSignal = average(@packetData[2]);
my $distance = 10**((27.55-(20*logten(2437))+abs($rawSignal))/20);
my @newClient = ($rawSignal, # Signal (dBm)
1, # Count
@packetData[0], # Source MAC
time(), # Last seen
$distance); # Distance (m)
$detectedClient{"@packetData[0]"} = [@newClient];
$uniqueClient++;
print "++ New probe request from @packetData[0] [$rawSignal dBm, $distance m]\n";
} else {
$detectedClient{"@packetData[0]"}[1]++;
$detectedClient{"@packetData[0]"}[3] = time();
}
}
for my $key2 (keys %detectedClient) {
#Signal, Count, MAC, Time
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($detectedClient{$key2}[3]);
my $lastSeen = sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
printf("!! %-20s %5s %-20s %20s %20s\n",
$detectedClient{$key2}[2],
$detectedClient{$key2}[1],
$lastSeen, $detectedClient{$key2}[0],
$detectedClient{$key2}[4],
);
}
输出:
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 18.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 19.
Scalar value @packetData[2] better written as $packetData[2] at a.pl line 20.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 24.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 27.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 29.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 31.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 32.
++ New probe request from foo [4.5 dBm, 0.0164302613184467 m]
!! foo 1 2016/05/16 15:19:38 4.5 0.0164302613184467
下一次,请提供一个最小的,可运行的问题演示。
用于整个阵列的语法是@array
但访问单个元件,这是(例如)$array[0]
此外,还有写在上下文内if
一个更好的方法。
第三,您使用的是detectedClient
的数组引用,因此语法可能会从$detectedClient{$smac}[1]++
更改为$detectedClient{$smac}->[1]++
,这对于意图而言会更清晰。我在下面的代码中更改了它,打印时也可以更改它。
这里的修改你的代码,以反映这一切,缩短到使用标:
my $smac = $packetData[0];
if ($smac ne "") {
if(! ref($detectedClient{$smac})) {
my $rawSignal = average($packetData[2]);
my $distance = 10**((27.55-(20*logten(2437))+abs($rawSignal))/20);
my @newClient = ($rawSignal, # Signal (dBm)
1, # Count
$smac, # Source MAC
time(), # Last seen
$distance); # Distance (m)
$detectedClient{$smac} = [@newClient];
$uniqueClient++;
print "++ New probe request from $smac [$rawSignal dBm, $distance m]\n";
} else {
my $ptr = $detectedClient{$smac};
$ptr->[1]++;
$ptr->[3] = time();
}
}
UPDATE:
应用使用标量和一点重新缩进时,打印代码如下:
for $key2 (keys %detectedClient) {
my $ptr = $detectedClient{$key2};
#Signal, Count, MAC, Time
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime($ptr->[3]);
my $lastSeen = sprintf("%04d/%02d/%02d %02d:%02d:%02d",
$year+1900, $mon+1, $mday, $hour, $min, $sec);
print STDOUT sprintf("!! %-20s %10s %-20s\n",
$ptr->[2], $ptr->[1],
$lastSeen, $ptr->[0], $ptr->[4]);
}
现在,有点容易看到[对我来说,至少;-)]格式是由两个字段短[所以最后两个参数将不会被打印]。
所以,这样的事情,而不是:
printf("!! %-20s %10s %-20s %10s %10s\n",
'$ foo { bar] [1]'与$ foo {bar} - > [1]'完全相同。括号/括号之间的箭头不是必需的。请阅读:http://perldoc.perl.org/perlreftut.html#Arrow-Rule –
@PaulL我误推了一个早期版本。这里,它们是必需的。另外,对于intent来说语法更清晰,[[我已经写了perl for 20+,并且有大约250,000行] –
除了代码之外,这是您需要更改的答案。您声称OP通过省略下标之间的箭头而造成语法错误。他没有。这不是任何错误。 –
总是使用'use strict;使用警告qw(全部);'! – ikegami
我有两个在脚本的顶部,但为了清晰而忽略它们(以及其余的脚本) – CyberJacob
@CyberJacob:如果你有'使用警告',那么你忽略了'Scalar value @packetData [ 0]更好地写为$ packetData [0]'。你为什么这样做? – Borodin