Операция сравнения Perl между переменной и элементом массива - PullRequest
1 голос
/ 16 августа 2011

У меня довольно много проблем с Perl-скриптом, который я пишу. Я хочу сравнить элемент массива с переменной, которую я должен увидеть, если они истинны. По какой-то причине я не могу заставить операцию сравнения работать правильно. Он будет либо всегда иметь значение true (даже если вывод обеих строк ясно показывает, что они не совпадают), либо он всегда будет ложным и никогда не будет оцениваться (даже если они одинаковы). Я нашел пример такой операции сравнения на другом сайте, но когда я ее использую, она не работает. Я что-то пропустил? Является ли тип переменной, взятый из файла, не строкой? (Насколько я могу судить, целое число не может быть целым, поскольку это 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 ]

3 голосов
/ 16 августа 2011
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 голос
/ 16 августа 2011

Когда вы читаете из такого файла, вы должны использовать 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 break.

Кроме того, из вашего комментария к ответу Джека:

Вот некоторый код, который вы можете использовать, чтобы узнать, сколько времени прошло с тех пор, как файл был изменен:

my $secondsSinceUpdate = time() - stat('filename.txt')->mtime;
0 голосов
/ 16 августа 2011

Когда вы читаете из такого файла, вы включаете символ конца строки (обычно \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-адрес как регулярное выражение (где . имеет особое значение), вероятно, не очень хорошая идея.

0 голосов
/ 16 августа 2011

Прежде всего, пожалуйста, не используйте 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.
}

Наконец, если вы используете версию Perl 5.10 или выше, вы можете использовать оператор интеллектуального сопоставления (т.е. ~~):

if($ipaddress~~@address)
{
  #You've got a match!
}
else
{
  #Nope, no matches.
}
0 голосов
/ 16 августа 2011

Возможно, у вас проблема с переводом строки.Попробуйте использовать chomp ($ address [$ i]).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...