我正在编写的Perl脚本遇到了很多麻烦。我想将数组的元素与变量进行比较,我必须看它们是否为真。出于某种原因,我似乎无法使比较操作正常工作。它将始终评估为真(即使输出两个字符串清楚地显示它们不相同),或者它将始终为假并且从不评估(即使它们是相同的)。我在另一个网站上找到了这种比较操作的一个例子,但是当我使用它时它不起作用。我错过了什么吗?我从文件中获取的变量类型不是字符串吗? (据我所知,它不能是一个整数,因为它是一个IP地址)。
$ipaddress = '192.43.2.130'
if ($address[0] == ' ')
{
open (FH, "serverips.txt") or die "Crossroads could not find a list of backend servers";
@address = <FH>;
close(FH);
print $address[0];
print $address[1];
}
for ($i = 0; $i < @address; $i++)
{
print "hello";
if ($address[$i] eq $ipaddress)
{print $address[$i];
$file = "server_$i";
print "I got here first";
goto SENDING;}
}
SENDING:
print " I am here";
我在Perl中相当弱,所以请原谅我在我的微弱代码中可能犯的任何新手错误/假设。谢谢你的时间。
答案 0 :(得分:3)
if ($address[0] == ' ')
{
open (FH, "serverips.txt") or die "Crossroads could not find a list of backend servers";
@address = <FH>;
close(FH);
此处此代码存在多个问题。首先你应该use strict
,因为它会告诉你@address
在定义之前被使用,你也在字符串上使用数字比较。
其次,您没有在文件中创建地址数组。您需要遍历文件的行以添加每个地址:
my @address = ();
while( my $addr = <FH> ) {
chomp($addr); # removes the newline character
push(@address, $addr);
}
但是你根本不需要进入阵列。只需遍历文件并找到IP即可。也不要使用goto
。这就是last
的用途。
while( my $addr = <FH> ) {
chomp($addr);
if( $addr eq $ipaddress ) {
$file = "server_$i";
print $addr,"\n";
print "I got here first"; # not sure what this means
last; # breaks out of the loop
}
}
答案 1 :(得分:1)
当你从这样的文件中读入时,你应该在与该行进行比较时使用chomp()
。当你这样做时:
print $address[0];
print $address[1];
即使您没有明确打印换行符,输出也会分成两行。那是因为$ address [$ i]最后包含一个换行符。 chomp
删除了此内容。
if ($address[$i] eq $ipaddress)
可以阅读
my $currentIP = $address[$i];
chomp($currentIP);
if ($currentIP eq $ipaddress)
熟悉chomp
后,您甚至可以使用:
chomp(my $currentIP = $address[$i]);
if ($currentIP eq $ipaddress)
另外,请使用goto
声明替换last
。那是perl相当于C的break
。
另外,根据你对杰克回答的评论:
这里有一些代码可用于查找自文件修改以来的时间:
my $secondsSinceUpdate = time() - stat('filename.txt')->mtime;
答案 2 :(得分:0)
您可能遇到换行问题。尝试使用chomp($ address [$ i])。
答案 3 :(得分:0)
当您从这样的文件中读取时,在每个元素中包含行尾字符(通常为\n
)。使用chomp @address;
来摆脱它。
另外,使用last;
退出循环;几乎不需要goto
。
这是一个相当惯用的代码重写。我排除了你可能需要的一些逻辑,但不清楚为什么:
$ipaddress = '192.43.2.130'
open (FH, "serverips.txt") or die "Crossroads could not find a list of backend servers";
while (<FH>) { # loop over the file, using the default input space
chomp; # remove end-of-line
last if ($_ eq $ipaddress); # a RE could easily be used here also, but keep the exact match
}
close(FH);
$file = "server_$."; # $. is the line number - it's not necessary to keep track yourself
print "The file is $file\n";
有些人不喜欢使用perl的隐式变量(如$_
和$.
),但他们并不难以跟踪。 perldoc perlvar
列出了所有这些变量,并解释了它们的用法。
关于完全匹配与“RE”(正则表达式,或正则表达式 - 请参阅perldoc perlre
了解大量详细信息) - 针对默认输入空间测试RE的语法($_
)很简单。而不是
last if ($_ eq $ipaddress);
你可以使用
last if (/$ipaddress/);
虽然将ip地址视为正则表达式(.
具有特殊含义)可能不是一个好主意。
答案 4 :(得分:0)
首先,请不要使用goto
。每当你使用goto
时,小耶稣在杀死一只小猫时哭泣。
其次,您的代码有点令人困惑,因为您似乎在开始@address
语句后填充if($address[0] == '')
(更不用说if
应该是if($address[0] eq '')
)。
如果您尝试将@address
的每个元素与$ipaddress
进行比较以获得相等性,则可以执行以下操作
注意:此代码假定您已填充@address
。
my $num_matches=0;
foreach(@address)
{
$num_matches++ if $_ eq $ipaddress;
}
if($num_matches)
{
#You've got a match! Do something.
}
else
{
#You don't have any matches. This may or may not be bad. Do something else.
}
或者,您可以使用grep
运算符从@address
获取所有匹配项:
my @matches=grep{$_ eq $ipaddress}@address;
if(@matches)
{
#You've got matches.
}
else
{
#Sorry, no matches.
}
最后,如果您使用的是5.10
或更高版本的Perl,则可以使用智能匹配运算符(即~~
):
if($ipaddress~~@address)
{
#You've got a match!
}
else
{
#Nope, no matches.
}