Reputation: 61
I am having quite a bit of trouble with a Perl script I am writing. I want to compare an element of an array to a variable I have to see if they are true. For some reason I cannot seem to get the comparison operation to work correctly. It will either evaluate at true all the time (even when outputting both strings clearly shows they are not the same), or it will always be false and never evaluate (even if they are the same). I have found an example of just this kind of comparison operation on another website, but when I use it it doesn't work. Am I missing something? Is the variable type I take from the file not a string? (Can't be an integer as far as I can tell as it is an IP address).
$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";
I am pretty weak in Perl, so forgive me for any rookie mistakes/assumptions I may have made in my very meager bit of code. Thank you for you time.
Upvotes: 1
Views: 3087
Reputation: 5071
When you're reading in from a file like that, you should use chomp()
when doing a comparison with that line. When you do:
print $address[0];
print $address[1];
The output is on two separate lines, even though you haven't explicitly printed a newline. That's because $address[$i] contains a newline at the end. chomp
removes this.
if ($address[$i] eq $ipaddress)
could read
my $currentIP = $address[$i];
chomp($currentIP);
if ($currentIP eq $ipaddress)
Once you're familiar with chomp
, you could even use:
chomp(my $currentIP = $address[$i]);
if ($currentIP eq $ipaddress)
Also, please replace the goto
with a last
statement. That's perl's equivalent of C's break
.
Also, from your comment on Jack's answer:
Here's some code you can use for finding how long it's been since a file was modified:
my $secondsSinceUpdate = time() - stat('filename.txt')->mtime;
Upvotes: 1
Reputation: 10582
When you read from a file like that you include the end-of-line character (generally \n
) in each element. Use chomp @address;
to get rid of it.
Also, use last;
to exit the loop; goto
is practically never needed.
Here's a rather idiomatic rewrite of your code. I'm excluding some of your logic that you might need, but isn't clear why:
$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";
Some people dislike using perl's implicit variables (like $_
and $.
) but they're not that hard to keep track of. perldoc perlvar
lists all these variables and explains their usage.
Regarding the exact match vs. "RE" (regular expression, or regexp - see perldoc perlre
for lots of gory details) -- the syntax for testing a RE against the default input space ($_
) is very simple. Instead of
last if ($_ eq $ipaddress);
you could use
last if (/$ipaddress/);
Although treating an ip address as a regular expression (where .
has a special meaning) is probably not a good idea.
Upvotes: 0
Reputation:
First of all, please don't use goto
. Every time you use goto
, the baby Jesus cries while killing a kitten.
Secondly, your code is a bit confusing in that you seem to be populating @address
after starting the if($address[0] == '')
statement (not to mention that that if
should be if($address[0] eq '')
).
If you're trying to compare each element of @address
with $ipaddress
for equality, you can do something like the following
Note: This code assumes that you've populated @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.
}
Alternatively, you can use the grep
operator to get any and all matches from @address
:
my @matches=grep{$_ eq $ipaddress}@address;
if(@matches)
{
#You've got matches.
}
else
{
#Sorry, no matches.
}
Finally, if you're using a version of Perl that is 5.10
or higher, you can use the smart match operator (ie ~~
):
if($ipaddress~~@address)
{
#You've got a match!
}
else
{
#Nope, no matches.
}
Upvotes: 0
Reputation: 19309
if ($address[0] == ' ')
{
open (FH, "serverips.txt") or die "Crossroads could not find a list of backend servers";
@address = <FH>;
close(FH);
You have several issues with this code here. First you should use strict
because it would tell you that @address
is being used before it's defined and you're also using numeric comparison on a string.
Secondly you aren't creating an array of the address in the file. You need to loop through the lines of the file to add each address:
my @address = ();
while( my $addr = <FH> ) {
chomp($addr); # removes the newline character
push(@address, $addr);
}
However you really don't need to push into an array at all. Just loop through the file and find the IP. Also don't use goto
. That's what last
is for.
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
}
}
Upvotes: 3
Reputation: 1507
You probably are having an issue with newlines. Try using chomp($address[$i]).
Upvotes: 0