变量和数组元素之间的Perl比较操作

时间:2011-08-16 16:58:11

标签: perl

我正在编写的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中相当弱,所以请原谅我在我的微弱代码中可能犯的任何新手错误/假设。谢谢你的时间。

5 个答案:

答案 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.
}