- ベストアンサー
ログファイルの記録数
# ログ更新 unshift(@new,"$num<>$addr\n"); open(OUT,">$logfile") || &error("Write Error: $logfile"); print OUT @new; close(OUT); 上記ログの書込みに、最大保存数を設定したいのですが、どのようにすればいいのでしょうか。 $max = 3; とした場合、3行超えたら古いファイルを消したいと考えています。よろしくお願いいたします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
暇だったので、一度KENTさんのを見てみました。一応解釈。 書き込み処理の手順 ・入力データのチェック ・ログファイル読み込み ・データの最大数チェック(ここ重要) ・登録チェック ・ログファイル更新(改造していたのはここ) 上手くいかない理由は、早い段階で最大数に関するエラー処理が入っているからではないでしょうか?例えば最大数が100の時、ファイルには100のデータがあるとすると、データ入力時に、三つ目の最大数チェックにより、その時点で何もできずにエラーとなります。後に削除コードを書いても、そこまで実行されません。 なので、227行目付近の最大数チェックのifから始まる三行をコメント化してみてはどうでしょう。(さすがに削除は後が怖い。残しておきましょう。) その上で、先ほどの処理を付け加えれば、上手くいくと思います。 先ほどの改造は「最大数チェック」と「その後の改良」なので、最大数チェックが二つあれば、先に書かれている方が優先されますよね? なので、コメントで無効化すれば、上手くいくと思います。実験してませんが。 KENTさんはプロですから、ソースに手順コメントで載っています。それを追えば、改造の手がかりになります。面倒でも、初めから見ていくと、改造のヒントになります。改造するスクリプト選びはとてもいいと思うので、がんばってください。
その他の回答 (4)
- g_p_
- ベストアンサー率53% (28/52)
最初は以下の様な感じかな?と思いましたが、 ># ログ更新 >unshift(@new,"$num<>$addr\n"); >open(OUT,">$logfile") || &error("Write Error: $logfile"); $#new = $max - 1 if scalar @new > $max; >print OUT @new; >close(OUT); これは、書き込みに行った時に多かったら古い行を捨てるって事になります。 >max値に到達してしまい、登録できなくなってしまうため これを回避するのとは意味が違いますね。 >KENT WEB のLink Visor(リンク集) これがどんな物か知りませんが、 @newの数と$maxを比べて、$maxの方が小さくない場合、 何らかのエラーとして処理してるんですかね? かなり強引ですが例えば、 ># ログ更新 my $limit_of_lines = $max - 1; >unshift(@new,"$num<>$addr\n"); >open(OUT,">$logfile") || &error("Write Error: $logfile"); $#new = $limit_of_lines - 1 if scalar @new > $limit_of_lines; >print OUT @new; >close(OUT); てしちゃえば、$max に 3 を指定したら、2行しか書き込まれなくなって、 $max を超える事は無くなるかも知れませんが…
お礼
ご回答有難うございます。 ご教授いただいた内容で上手くいきました。ただ、よく見てみましたら、利用しているCGIではデータの並び順が、カテゴリ別に複雑にならんでおりまして、古いデータからではなく、下層のカテゴリに登録されているデータから削除されてしまいました。これも、カテゴリを一つにして解決しました。
- W_H
- ベストアンサー率47% (21/44)
>>一生、回答されている方々のレベルに到達することは不可能のような気がしています。 大丈夫です。ぼくも全く同じ処理を、perlを始めた頃に書きました。ただ、popとpushしか知らなかったので、データを書き込むごとに、新規データを消していくというお笑い的なプログラムができました。unshiftとかを知っている分、そのころのぼくよりまだましかと(笑。 サンプルソースを載せておきます。さっきのはこれの一部分を載せました。 @new=(1,2,3,4,5); $max=3; --$max; while($#new>$max){ pop(@new); } print @new; これを実行すると、123と表示されます。変数や配列の名前が同じなので、こいつを元に試行錯誤してみてください。 ついでに、pop等の使い方はあってます。
お礼
ご回答有難うございます。 お教え頂いたサンプルソースを元に、試行錯誤して少しでも理解を深めたいと思います。お付き合いいただき有難うございました。
- W_H
- ベストアンサー率47% (21/44)
ファイルではなく、データではないでしょうか。 一応unshiftの行の次に、これを入れてみてください。 --$max; while($#new>$max){pop(@new);} $#配列名で、配列の数が分かります。ただ、数え方が配列なので、1からではなく、0から始まります。よって、データが五つ入っていれば、4という数字を返します。なので、$maxから1を引くか、$#newに1を足す必要があります。一応$maxを一度いじった方が楽なので、始めにデクリメントしています。 データですが、配列に入っているようなので、一番最後のデータを取り除く(本当は$変数=の形で使って、データを読み出すんだけど、見た目削除にも使える)pop関数を、データが$maxを超えている分だけ実行するループに入れています。 ちなみに、配列の先頭からデータを削除(本当は削除と読み込み)するのがshift(@配列)で、配列の末尾にデータを追加するのがpush(@配列,データ)です。shift、unshift、pop、pushをまとめて覚えておくと、便利です。(例えば、新しいデータを末尾に付け加え、古いデータは先頭から取り除くことも可能。)
お礼
ご回答ありがとうございます。 shift、unshift、pop、pushについて検索してみました。 古いデータから消す場合は、 unshiftが使われていたらpopで取り除き、 pushが使われていたらshiftで取り除くという具合でしょうか。 間違っていたらすみません。毎日少しずつ勉強しているのですが、意味のわからないことが多すぎて、自分には一生、回答されている方々のレベルに到達することは不可能のような気がしています。 教えていただいた文を追加して試行錯誤してみましたが、付け足す行が間違っているのか、古いデータは削除されていないようでした。shift、unshift、pop、pushについてもう少し詳しく調べてみてからもう一度挑戦してみようと思います。
- g_p_
- ベストアンサー率53% (28/52)
こんにちは、 >3行超えたら古いファイルを消したいと考えています。 ファイルを消すんですか? じゃなくて、もし、単に古い行を捨てて書き込みたいのなら、 >unshift(@new,"$num<>$addr\n"); unshift してる様子なので、 $#new = $max - 1 if scalar @new > $max; して配列を詰めてしまえばいいんでしょうけど。
お礼
ご回答有難うございます。 申し訳ありません、説明がおかしかったです。ファイルでなくデータでした。利用しているCGIはKENT WEB のLink Visor(リンク集)なのですが、1日100件前後の登録があります。(ほとんど海外からのスパム登録です。汗) そのため、あっというまにmax値に到達してしまい、登録できなくなってしまうため、登録の度に常に古いリンクから消していけば問題解決?というか、勉強の意味もこめて今回の改造に挑んでみました。Perlは素人レベルのため、わからないことだらけですので、わかりやすくご説明していただけて感謝です。 ただ、大変もうしわけないのですが、Link Visorが複雑な仕様?になっているようで、なかなか上手くいきません。よろしければ、ソースのどの部分にどのような文字列を追加すればよろしいのかご指導いただければ幸いです。
お礼
ご回答有難うございます。 確かに先にエラー処理が実行されていては駄目ですね。うっかりしていました。無効化しましたら、お教え頂いた方法で上手くいきました。本当にご丁寧にお教え頂き、g_p_様とW_H様に感謝です。