- ベストアンサー
ファイルを読み込んで特定の箇所のデータを表示
お世話になります。 掲示板のログファイルから、特定の箇所のデータを取得して表示させたいと思っています。 log.cgi(パーミッション666) ログデータの中身 3<><><> 3<><><><><><><> 2<><><><><><><> 1<><><><><><><> 上記のような感じになっており、「<>」と「<>」の間にいろいろなデータが入っています。 1行目の最初の数字が、これまで投稿された記事総数になっており、この数字を取得したいと思っています。 log.cgiを読み込んで、この記事総数を「$allnumber」と記述すれば、その箇所に表示させるにはどのようにすれば良いでしょうか。 ご教授をお願い致します。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
ごめんなさい、勘違いしてますね私。 さっきまでのは無視でお願いします。 要は、最初の一行と全行数だけが必要な訳なんですね。 あんまり良い方法が思い浮かばないんですが、一応、思いつきで書きます。 なので、他の方の回答を待たれた方が良い回答をもらえるかも知れません。 とりあえず質問者さんのスクリプトをいじって、 #! perl use strict; my $room = q(.); open(FH, "$room/log.cgi") or die "Can't open $room/log.cgi"; my $line = <FH>; my( $allnumber ) = $line =~ /^(\d*)/; my $count; $count = $. while (<FH>); close(FH); print qq($allnumber : $count); こんな感じでしょうか? 最初の行は行数に含めないんですよね?(違います?) で、別な方法です。 ---- あんまり良くなさそうな、配列に一気に取り込む例 ---- #! perl use strict; my $room = q(.); open my $fh , '<' , "$room/log.cgi" or die $!; my @lines = <$fh>; close $fh or die $!; my( $allnumber ) = $lines[0] =~ /^(\d*)/; my $count = @lines - 1;# 最初の行の分を1引く print qq($allnumber : $count); ---- Tie::File を使ってみた例 ---- #! perl use strict; use Tie::File; my $room = q(.); tie my @array, 'Tie::File', "$room/log.cgi" or die $!; my( $allnumber ) = $array[0] =~ /^(\d*)/; my $count = @array - 1;#最初の行はカウントしない? print qq($allnumber : $count);
その他の回答 (5)
- sakusaker7
- ベストアンサー率62% (800/1280)
>1つにまとめるには正確にはどのように記述して良いのか分からないので、下記のスクリプトをどのようにしたら良いでしょうか。 #3の回答にあるスクリプトで何か問題点とか不満な点があるんでしょうか? open(FH, "$room/log.cgi") or die "Can't open $room/log.cgi"; my $count; $count = $. while (<FH>); close(FH); open(FH, "$room/log.cgi") or die; my $line = <FH>; my( $allnumber ) = $line =~ /^(?d*)/; close(FH); どうしてもこの方向でやりたいということなら use strict; my $room = #適当な値をどうぞ q{.}; open my $fh, '<', "$room/log.cgi" or die "Can't open $room/log.cgi ($!)"; my $line = <$fh>; my ($allnumber) = $line =~ /^(\d+)/; 1 while (<$fh>); my $count = $.; close $fh; print "$allnumber : $count\n"; こんな感じでしょうか。 毎回毎回 $. の値をとらないでも、ループが終了した後で 値をとれば問題ありません。
お礼
ご回答ありがとうございます。 >#3の回答にあるスクリプトで何か問題点とか不満な点があるんでしょうか? いえいえ、そういう訳ではないのですが、この記述がスマートな書き方でなかったり、サーバに少し負担増になってしまうのであれば、他の記述方法があるのかと思いました。 動作自体には問題はないので、この方法で進めて行こうと思います。
- g_p_
- ベストアンサー率53% (28/52)
こんにちは、 犯人は >my $room = q(.); これです。そちらの設定を上書きしているのでしょう。 これは単にこちらでエラーが出ないように書いただけだったんで、 そちらでうまい事やってもらえると思っていたんですが… 断っていなかった私が悪かったです、ごめんなさい。 そのせいで、たどり着いたコードだったんでしょうけど、 同じファイルを二度開くのはあまりにもアレなんで、 もう少し考えられた方が良いかもですね。
お礼
ご回答ありがとうございます。 >断っていなかった私が悪かったです、ごめんなさい。 いえいえ、とんでもありません(ー_ー) 私はほとんどperlは分からず、何か改造をしようと思ったら、検索して調べて何とかしている程度なので、アドバイスを頂けるだけでも感謝しております。 >同じファイルを二度開くのはあまりにもアレなんで、 そうですね。確かに同じファイルを2度開いているのですが、1つにまとめるには正確にはどのように記述して良いのか分からないので、下記のスクリプトをどのようにしたら良いでしょうか。 お手数をおかけしますが、ご教授頂けると助かります。 -------------------------- open(FH, "$room/log.cgi") or die "Can't open $room/log.cgi"; my $count; $count = $. while (<FH>); close(FH); open(FH, "$room/log.cgi") or die; my $line = <FH>; my( $allnumber ) = $line =~ /^(?d*)/; close(FH); --------------------------
- chaimasuka
- ベストアンサー率57% (26/45)
> No such file or directory at ./~(書き込んだファイルのパス) line 812. ログファイルのパスの指定が間違っているのでは?
お礼
ご回答ありがとうございます。 ログファイルのパスは、フルパスで指定してみましたが、ダメでした。 どこで配布されているCGIか、お教えした方が良いですか? 複雑な処理でないと思い、最低限必要だと思う情報のみしか記載しませんでした。 お手数をおかけしますが、引き続きアドバイスをお願い致します。
補足
無事に解決しました(^^) NO3さんの「補足」で解決した方法を記載しておきましたので、よろしければご覧になって下さい。 とりあえず、無事に動作して良かったです。
- g_p_
- ベストアンサー率53% (28/52)
>記述してみましたが、エラーが出て動作しませんでした。 そうですか…。 できれば、どんなエラーだったとか、どんな風に書いたとか補足してもらえると良いんですが…。 >my( $allnumber ) = $line =~ /^(\d*)/; 上のコードで、 読み込んだ行の先頭にある数字の塊を $allnumber に取得しているつもりなんですけどね。
お礼
ご回答ありがとうございます。 エラー(500)は下記のように表示されます。 No such file or directory at ./~(書き込んだファイルのパス) line 812. ちなみに、ログファイルの桁数のカウントは下記のように記述しています。 #ログファイルの行数のカウント open(FH, "$room/log.cgi") or die "Can't open $room/log.cgi"; my $count; $count = $. while (<FH>); close(FH); 上記の場合、表示したい箇所に$countと記載すれば、ログファイルの行数が表示されるようになっています。 アドバイスをお願いします。
- g_p_
- ベストアンサー率53% (28/52)
こんにちは、こんな感じでしょうか #! perl use strict; open my $fh, '<', 'log.cgi' or die $!; while (my $line = <$fh>) { my( $allnumber ) = $line =~ /^(\d*)/; print qq($allnumber\n); } close $fh or die $!; __END__
お礼
ご回答ありがとうございます。 教えて頂いたのを記述してみましたが、エラーが出て動作しませんでした。 掲示板CGIの中に、記述したいと思っています。 掲示板CGIの本体からログファイルまでのパスは、正確には「$logdir/log.cgi」となっており、$logdirにはログファイルが入っているディレクトリ名が入ります。 よろしくお願いします。
お礼
ご回答ありがとうございます。 下記の様に書き換えてみました。 ---------------------------------- open(FH, "$room/log.cgi") or die "Can't open $room/log.cgi"; my $count; $count = $. while (<FH>); close(FH); ---------------------------------- ↓ ---------------------------------- my $room = q(.); open(FH, "$room/log.cgi") or die "Can't open $room/log.cgi"; my $line = <FH>; my( $allnumber ) = $line =~ /^(?d*)/; my $count; $count = $. while (<FH>); close(FH); print qq($allnumber : $count); ---------------------------------- すると、下記のようなエラー(500)が表示されました。 Can't open ./log.cgi at ./書き込んだファイルのパス line 814, line 6. ログファイルまでのパスは間違っていないと思うのですが、httpから始まるフルパスでログファイルを指定してみましたが、やはりダメでした。 フルパスで指定した場合も、同じエラーが表示されました。 ログファイルのパーミッションは666になっています。 エラー内容をみると、ログファイルを開く事ができないと出ているみたいですが、ログファイルの行数だけをカウントするだけの場合は、同じログファイルのパス指定($room/log.cgi)とすれば、行数を表示する事ができています。 何が悪いのか分からない状態です。 またログファイルと教えて頂いたスクリプトのみで動作させてみましたが、やはりダメでした。 「test.cgi」の中身です。test.cgi(755)とlog.cgi(666)は同じディレクトリに入れました。 ------------------------------ #!/usr/local/bin/perl use strict; #my $room = q(.); open(FH, "log.cgi") or die "Can't open log.cgi"; my $line = <FH>; my( $allnumber ) = $line =~ /^(?d*)/; #my $count; #$count = $. while (<FH>); close(FH); print qq($allnumber); __END__ ------------------------------ お手数をおかけしますが、引き続きアドバイスをお願い致します。
補足
いろいろと自分なりに試していたら、無事に動作する事ができました(^^) 下記のように、行数カウントと分けて記述してみました。 -------------------------- open(FH, "$room/log.cgi") or die "Can't open $room/log.cgi"; my $count; $count = $. while (<FH>); close(FH); open(FH, "$room/log.cgi") or die; my $line = <FH>; my( $allnumber ) = $line =~ /^(?d*)/; close(FH); -------------------------- いったい何が悪かったのでしょうか? 原因が分からないのですが、もし推測できそうでしたら今後のためにアドバイスを頂けると助かります。 よろしくお願いします。