• ベストアンサー

Perlの書き方

$addr = $ENV{'REMOTE_ADDR'}; open(IN,"$log"); my @data = <DATA>; foreach(@data){ my($ip)=split(/\,/,$_); if($ip==$addr){$a=1;} if ($a !=1) { 処理1 } else { 処理2 } } close(DATA); $logに$addrが含まれている場合は処理2を実行させたいと↑のスクリプトを書いてみました。私の環境(パソコンの環境と、設置サーバーの環境)では正常に動いているようですが、人に(パソコンの環境と、設置サーバーの環境)よっては、処理1が実行されてしまうようです。書き方は、これで間違っていませんでしょうか? もし間違っていないのでしたら、環境によって$logに$ipが記録されていないのかも知れません。perlの知識はあまりありませんが、よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

・open が成功したかチェックしていない ・open(IN,"$log"); の $logを囲むダブルクォートは不要 ・open でオープンしているのがINなのに、配列に読み込んでいるのはDATAから ・split(/\,/,$_); ',' は特殊な文字ではないのでエスケープ不要 ・if($ip==$addr){$a=1;} $ip、$addrにはIPアドレスを表す「文字列」 が入っているので、== による比較を指定はいけない。 また、$a, $bという名前の変数は使うべきでない #!/usr/bin/perl use strict; use warnings; my $addr = $ENV{REMOTE_ADDR} || "192.168.1.1"; my $log = 'accesslog.dat'; open my $in, $log or die $!; my @data = <$in>; close $in; foreach my $line (@data) { my ($ip) = split q{,}, $line; if ($ip eq $addr) { print "$addr が見つかった\n"; } else { print "$addr ではなかった($ip)\n"; } }

yasainet
質問者

お礼

ありがとうございます。大変勉強になりました。

その他の回答 (2)

  • g_p_
  • ベストアンサー率53% (28/52)
回答No.3

>$found = 1 if /^$addr/; なんですけど、明らかにまずいですね、あんまり深く考えていませんでした。すみません。 せめて $found = 1 if /^${addr},/; なら、何とか使えますかね。 my($ip) = split /,/; if ( $ip eq $addr ) { $found = 1; } の方がいいかな? >last if$found;は、$foundを全て読み終わったらループを終了させるという意味でよろしいでしょうか? $found は単に、結果がどうだったか保存しておく変数です。勝手に書きました。 last ってのは、一番内側のループを終了させる時に使います。 一番内側でないループを抜けるなら、ラベルが必要です。 last if ~ ; はいわゆる慣用句ってヤツですかね。結構良く見る気がします。 ~ が真なら、ループを終了って感じです。 Perl は if ( 条件 ) { 処理 } を 処理 if 条件; て書いても同じなんで、そう書いた方が見易い場合(好み?)にそう書きます。

yasainet
質問者

お礼

有難うございました。今まではローカルでテストして問題なければ大丈夫だと心配していませんでしたが、サーバーに迷惑をかけては大変ですので、ループの終了方法に関してはしっかり勉強してみます。

  • g_p_
  • ベストアンサー率53% (28/52)
回答No.2

sakusaker7 さんの指摘以外で気になったので… >$logに$addrが含まれている場合は処理2を実行させたいと 1行ずつテストしたいなら、$a はループの最初で初期化しないとアレだし、 ファイル全体であるかないかなら、見つかった時点でループを終わるようにした方が いいんじゃないですかね? sakusaker7 さんのスクリプト借りてループを終わる例です。 #!/usr/bin/perl use strict; use warnings; my $addr = $ENV{REMOTE_ADDR} || "192.168.1.1"; my $log = 'accesslog.dat'; open my $in , '<' , $log or die $!; my $found; while (<$in>) { $found = 1 if /^$addr/; last if $found; } close $in; if ( $found ) { print "あった\n"; } else { print "なかった\n"; }

yasainet
質問者

お礼

ありがとうございます。大変勉強になりました。 last if$found;は、$foundを全て読み終わったらループを終了させるという意味でよろしいでしょうか?

関連するQ&A

専門家に質問してみよう