• ベストアンサー

ファイルを読み込んで特定の箇所のデータを表示

お世話になります。 掲示板のログファイルから、特定の箇所のデータを取得して表示させたいと思っています。 log.cgi(パーミッション666) ログデータの中身 3<><><> 3<><><><><><><> 2<><><><><><><> 1<><><><><><><> 上記のような感じになっており、「<>」と「<>」の間にいろいろなデータが入っています。 1行目の最初の数字が、これまで投稿された記事総数になっており、この数字を取得したいと思っています。 log.cgiを読み込んで、この記事総数を「$allnumber」と記述すれば、その箇所に表示させるにはどのようにすれば良いでしょうか。 ご教授をお願い致します。

  • Perl
  • 回答数6
  • ありがとう数6

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

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

ごめんなさい、勘違いしてますね私。 さっきまでのは無視でお願いします。 要は、最初の一行と全行数だけが必要な訳なんですね。 あんまり良い方法が思い浮かばないんですが、一応、思いつきで書きます。 なので、他の方の回答を待たれた方が良い回答をもらえるかも知れません。 とりあえず質問者さんのスクリプトをいじって、 #! 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);

mintroll
質問者

お礼

ご回答ありがとうございます。 下記の様に書き換えてみました。 ---------------------------------- 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__ ------------------------------ お手数をおかけしますが、引き続きアドバイスをお願い致します。

mintroll
質問者

補足

いろいろと自分なりに試していたら、無事に動作する事ができました(^^) 下記のように、行数カウントと分けて記述してみました。 -------------------------- 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); -------------------------- いったい何が悪かったのでしょうか? 原因が分からないのですが、もし推測できそうでしたら今後のためにアドバイスを頂けると助かります。 よろしくお願いします。

その他の回答 (5)

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

>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"; こんな感じでしょうか。 毎回毎回 $. の値をとらないでも、ループが終了した後で 値をとれば問題ありません。

mintroll
質問者

お礼

ご回答ありがとうございます。 >#3の回答にあるスクリプトで何か問題点とか不満な点があるんでしょうか? いえいえ、そういう訳ではないのですが、この記述がスマートな書き方でなかったり、サーバに少し負担増になってしまうのであれば、他の記述方法があるのかと思いました。 動作自体には問題はないので、この方法で進めて行こうと思います。

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

こんにちは、 犯人は >my $room = q(.); これです。そちらの設定を上書きしているのでしょう。 これは単にこちらでエラーが出ないように書いただけだったんで、 そちらでうまい事やってもらえると思っていたんですが… 断っていなかった私が悪かったです、ごめんなさい。 そのせいで、たどり着いたコードだったんでしょうけど、 同じファイルを二度開くのはあまりにもアレなんで、 もう少し考えられた方が良いかもですね。

mintroll
質問者

お礼

ご回答ありがとうございます。 >断っていなかった私が悪かったです、ごめんなさい。 いえいえ、とんでもありません(ー_ー) 私はほとんど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); --------------------------

回答No.4

> No such file or directory at ./~(書き込んだファイルのパス) line 812. ログファイルのパスの指定が間違っているのでは?

mintroll
質問者

お礼

ご回答ありがとうございます。 ログファイルのパスは、フルパスで指定してみましたが、ダメでした。 どこで配布されているCGIか、お教えした方が良いですか? 複雑な処理でないと思い、最低限必要だと思う情報のみしか記載しませんでした。 お手数をおかけしますが、引き続きアドバイスをお願い致します。

mintroll
質問者

補足

無事に解決しました(^^) NO3さんの「補足」で解決した方法を記載しておきましたので、よろしければご覧になって下さい。 とりあえず、無事に動作して良かったです。

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

>記述してみましたが、エラーが出て動作しませんでした。 そうですか…。 できれば、どんなエラーだったとか、どんな風に書いたとか補足してもらえると良いんですが…。 >my( $allnumber ) = $line =~ /^(\d*)/; 上のコードで、 読み込んだ行の先頭にある数字の塊を $allnumber に取得しているつもりなんですけどね。

mintroll
質問者

お礼

ご回答ありがとうございます。 エラー(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)
回答No.1

こんにちは、こんな感じでしょうか #! 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__

mintroll
質問者

お礼

ご回答ありがとうございます。 教えて頂いたのを記述してみましたが、エラーが出て動作しませんでした。 掲示板CGIの中に、記述したいと思っています。 掲示板CGIの本体からログファイルまでのパスは、正確には「$logdir/log.cgi」となっており、$logdirにはログファイルが入っているディレクトリ名が入ります。 よろしくお願いします。

関連するQ&A

  • 最終更新日自動取得のようなCGIは難しいでしょうか

    お世話になります。 掲示板のログを、CGIにアクセスしただけで表示させたいと思っています。 掲示板CGIの中に下記の記述を加えているため、掲示板の中で表示させたい箇所に$allnumberと記述する事で、投稿記事の総数を表示できるようになっています。 -------------------- #総投記事数を表示 open(FH, "$room/log.cgi") or die; my $line = <FH>; my( $allnumber ) = $line =~ /^(?d*)/; close(FH); -------------------- マルチ掲示板CGIを使用しているので、$roomには各掲示板のIDが入力されます。 各掲示板の投稿数を表示する、単独のCGIスクリプトは難しいでしょうか。 最終更新日を自動的に取得して、表示するCGIのイメージです。 これらのCGI(仮に「lastup.cgi」とします)は、http://hogehoge.jp/lastup.cgi?./bbs/log.cgiと最終更新日を取得したいファイルを指定して、htmlファイルの表示させたい箇所に記述すると、指定したファイルの最終更新日が表示できるようになっているCGIがあります。 (※「./bbs/log.cgi」は、lastup.cgiから見た対象ファイルまでのパスです) (※「log.cgi」は、掲示板のログが保存されているファイルとします) このように、「http://hogehoge.com/~.cgi?./(掲示板ID)/log.cgi」と記述するだけで、htmlの好きな箇所に指定した掲示板の記事数を表示させるようなCGIはできないでしょうか。 私はこれまでにCGIをいくつか設置した経験や、改造した経験はありますが、いつもネットで検索して分かる範囲で簡単な改造しかできません。 お手数ではありますが、できる限り詳しく教えて頂けると嬉しく思います。 お力添えを頂けると助かります。 何卒、よろしく御願い致します。

  • 表示がうまく出来ません

    2peasで配布しているCGIを使って掲示板を設置しようと思ったので 掲示板用のスキンをDLしたのですが、FTPでアップしてパーミッションも書き換えて アップしたCGIにアクセスしたら、一応きちんと設置は出来ているんですが ログがなぜか他のスキンのものが表示されているんです。 (cgi-binフォルダに他の掲示板スキンがあるのですが、その他の掲示板のログが アップしたばかりの掲示板に表示されてしまう、ということです) きちんと***.datのファイル名も書き換えました なぜ他のログが表示されてしまうんでしょうか・・・? 説明が下手で申し訳ありませんが、よろしければアドバイス下さい。よろしくお願いします。

    • 締切済み
    • CGI
  • データ件数が多いことによってログが消えたりしますか?

    1500件ほどのログデータがあります。(.txt) このログデータに追加をしたり、修正を加えています。 (cgiを使って) 最近気づいたのですが、以前入力したはずのものが消えていたりするんです。 でも全部が消えるわけではなく、一部が消えるので、プログラムのミスではなさそうなんですが。 このログデータ+cgiは社内のサーバーにアップデートして使用しています。 以前はWeb用のサーバーにおいてあり、使用していましたが、データが消えた?というようなことはなかったのですが、 社内の方においてからそのようなことがおきているのではないかと思うようになりました。 社内の人はそこへは入らない(入れない)ので、もし攻撃を受けているとしたら外部からなのかな?と思い、ログをコピーし、 ローカルに保存しておき、数日たってから中身を照合しようとは思っています。 ですが、あんまりその可能性は考えられないので、それ以外に理由があるのかな?と思ってます。 件数が多いことでログデータが勝手に削除されたりすることはあるのでしょうか? ※cgiはperlでかいています。

    • ベストアンサー
    • CGI
  • ログデータの改行を非表示に

    自分のメモ用に、簡単な掲示板を作りました。 ログデータだけを見た時、見やすいよう(長文なので)に1文ずつに改行を入れています。 -----ログデータの例(1文ごとに\nで改行)-------- 11月11日、支払なんちゃらかんちゃら~ 11月12日、会議なんちゃらかんちゃら~ 11月23日、休みなんちゃらかんちゃら~ ---------------------------------------- これを以下のように表示させたく -----表示------------------ 11月11日、支払なんちゃらかんちゃら~ 11月12日、会議なんちゃらかんちゃら~ 11月23日、休みなんちゃらかんちゃら~ --------------------------- その表示部分のプログラムは $log = file("log.txt"); foreach($log as $val){  if(!empty($val)){   echo "{$val}<br>";   } } と記述しているのですが、改行だけの行も表示されてしまいます。 if文を、!emptyの他に、$val!==nullや、isset($val)で試しても 改行だけの行も表示されてしまうのですが・・・ 改行だけの行は表示しないようにするにはどのように記述すればよいのでしょうか?? ご教授よろしくお願いします。

    • ベストアンサー
    • PHP
  • ログファイルのデーターから特定して表示させる

    例えば、掲示板とかブログ日記などの各記事に対して付けたコメントを ログファイルに保存し、そのログファイルの中から、その時付けた記事に 対してコメントを、その記事の所に表示させるにはどうしたらよいでしょうか? 出来れば具体的に、ソース説明で… 「ここの部分がこうで…この部分をこう記入…この関数の意味はこうです」 「インデックスの付け方はこうです。…こうするとインデックスが付けれます」 …と言った様に、実際に仕組み説明をソースで詳しくして頂けると助かります。 ※ データーベースは利用せず。 PHPプログラムだけで行いたい。 ※ 次の様な感じで追加モード「a」で単に書込みしてます。 <?php $fp = fopen("log.txt","a"); fputs($fp,$body); fclose($fp); ?> ※ 次の様な感じで file() で読み出しはできます。 <?php $data = file("log.txt"); for($i=0; $i<sizeof($data); $i++){ print "${data[$i]}<br>\n"; } ?> ただ、この呼び出し方法だと、例えば、log.txt に次ぎの様にデーターが保存(収納)されていた場合… 名前:テスト君1,コメント:あああ 名前:テスト君2,コメント:いいい 名前:テスト君3,コメント:ううう 名前:テスト君3,コメント:えええ 名前:テスト君3,コメント:おおお ……呼び出した時に、「名前:テスト君1,コメント:あああ」から順に呼び出され表示します。 ですので例えば… Aの場所で書いた記事に対して付けたコメントが、「名前:テスト君3,コメント:ううう」だとします。 Bの場所で書いた記事に対して付けたコメントが、「名前:テスト君2,コメント:いいい」だとします。 それを… Aの場所の所に、「名前:テスト君3,コメント:ううう」 Bの場所の所に、「名前:テスト君2,コメント:いいい」 …と言う様に、各記事に対して付けたコメントを、各記事で付けた場所に表示させたいのです。 その方法、やり方、仕組み、コツなどが分かりません。

    • ベストアンサー
    • PHP
  • CGI(BBS)の設置が出来ません(1)

    掲示板CGIサンプルをDLして設置作業を行っていますがうまく設置できません。 まず、サンプルをDLすると、以下の8書類が表示されました。 ・●●●.html(記事入力のHTML) ・●●●.html(記事表示のHTML) ・●●●.html(過去記事表示のHTML) ※HTMLのパーミッションは「666」に設定 ・jcode.pl(644に設定) ・bbs.cgi(755に設定) ・bbs.log(666に設定) ・bbs2.cgi(755に設定) ・pastno.dat(666に設定) ・プロバイダで指定されたPerlへのパス #!/usr/local/bin/perl CGIはプロバイダから指定されたcgi-binへアップしました。パーミッションの設定も上記の様に行いました。 ただ、bbs.cgiのソース(?)の中でよく分からない個所がありました。 (2)へ続く

    • 締切済み
    • CGI
  • htmlから、ファイル、もしくはCGI実行結果を表示

    htmlのページを開いたときに、部分的にCGIの実行結果、もしくはファイルの中身を表示することは出来ないでしょうか。「インラインフレームを設けて・・・」という意味ではなく、たとえばページを開くごとにある行の数字だけ数字が増えていく、といったカウンターのようなことが出来るようにしたい。 そういうCGIスクリプトを作っているので、CGIをまったく使わないというのは無しで、またSSIは使わないこと前提でお願いします。

    • ベストアンサー
    • Perl
  • apeboard+にて旧.datファイルのログを表示させられない

    apeboard+にて以前のログを表示させたいのですが、何度チャレンジしてもうまくいかないため、詳しい方にお知恵をお貸し頂きたく質問させて頂きました。 そもそも、datファイルを少し触ってアップしなおしたところ、掲示板にログが表示されなくなってしまい、パスワードも受け付けなくなってしまいました。 そこで、同じ名前をつけた空のdat(0bite)ファイルをアップロードし、新たにパスワードを設定した後、そのdatファイルをダウンロード。一行目に書かれているパスワードの暗号をコピー。そして、ログデータの入った旧datファイルの一行目に暗号をペーストして、アップロードしました。 ※アップロードするdatファイルのファイル名は、boardni.cgiのデータファイルの場所を示す部分と同じ名前であることは確認しております。 空のdatファイルでパスワードを指定した時は管理画面へのパスワードを受け付けてくれるのですが、一行目を書き直した旧datファイルをアップロードしなおすと、パスワードを受け付けなくなり、古いログも表示してくれません。新しい書き込みは表示されますが、クッキーをオンにしてパスワードを入れて書きこまないと、表示がおかしくなります。 試しに、空のdatファイルに一行目の暗号だけを記載してアップロードしてみたのですが、同じ現象がおきました。 上記において、何か手がかりになりそうな事がありましたらアドバイス頂けると助かります。

    • 締切済み
    • CGI
  • perl使用のCGIでのデータファイルの取り扱いについて

    こんにちは、 perlでCGIを動かしているんですが 掲示板やアクセスログなどのデータファイルの置き場所についてこまっています perlのopen関数などでファイルを開くことはできても、直接URLを指定すれば 見ることができてしまいまます。 内部の実行からは読み書きできて、直接URLを指定したら、アクセス拒否にする というパーミッションの設定or.htaccessなどの設定方法があれば教えてください。

    • ベストアンサー
    • CGI
  • 掲示板のログとカウンターの数字が同時に消えました!

    ニフティでホームページを作っています。 フリーのCGIで配布されているカウンターと、掲示板(別々のところの)を使っていましたが、気づいたら掲示板のログが消えて、カウンターも1に戻っていました。 調べたところ、カウンターの数字を記憶しているdatファイルはサーバーにあったのですが、中身が白紙になっていました。数字が全くないのです。 カウンターは1のままで誰が何度クリックしても 数字は増えなくなっていました。掲示板は真っ白で書き込みもできなくなりました。 掲示板のログを記録しているdatファイルが存在してるのに中身だけ消えて白紙になってました。 (掲示板のログのdatファイルは四つあり、現在の分の一番新しいものだけが中身が消えてました。) ニフティに聞いても、なにも操作はしてないといわれそのCGIのエラーではないかといわれましたが、同時に二つのものが壊れるとは考えられないのです。 最近はファイルのアップロードもしていなかったので、間違えて削除したとは考えられません。 しかもファイルがないならともかく中身だけ白紙に戻るとは、何が起こったのか全くわからないのです。 原因がわかる方がいらしたら、教えてください。 ログを戻すことはやっぱり不可能ですよね。消えてるわけだから。また同じことにならないようにしたいので、何かありましたら教えてください。 中身が消えたファイルは「Daycount.dat」と「4.dat」という名前です。

専門家に質問してみよう