![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
ここで教えてもらってログファイルの書き方(挿入のようなカンジで)をやってみたんですが、どうしても思い通りの動きをしません。
希望としては、IDが一緒なら、その同じIDの下に書き込みを行う。同じIDが見つからなければ、一番上に書き込みを行う。
というようにしたいのです。
上記のことを行うために以下のコードを書きました。
---------------
for ($w=0;$w<$gyou+1;$w++){
@log3 = split(/&/,$log2[$w]);
foreach(@log3){
($keyw,$valuew) = split(/=/,$_);
$FORMw{$keyw} = $valuew;
}#foreach
open(FH3,">>log.log");
if ($ID == $FORMw{'ID'}){
print
FH3"ID=$ID&COUNT=$COUNT&TITLE=$TITLE&NAME=$NAME&PASSWORD=$PASSWORD&NAKAMI=$NAKAMI&COLOR=$COLOR&TIME=$year/$m
on/$day $hour:$min:$sec&SEARCHKEY=$year$mon$day$hour$min$sec\n";
last;
} else {
if($w+1 == $gyou){
print
FH3"ID=$ID&COUNT=$COUNT&TITLE=$TITLE&NAME=$NAME&PASSWORD=$PASSWORD&NAKAMI=$NAKAMI&COLOR=$COLOR&TIME=$year/$m
on/$day $hour:$min:$sec&SEARCHKEY=$year$mon$day$hour$min$sec\n";
close(FH3);
}
}
}#for
---------------
どうしてもログファイルの最新情報としてしか書き込みがされません。
また、最新ログを1番上に書き込む、ということをしたいのですができますか?
日付順などで並べ替えをしてしまうと、ぐちゃぐちゃになってしまうので、並べ替えを行わずに、です。
またこのような書き込みの仕方をしなくても、
例えば並べ替えで、Excelみたいに、1番目と3番目を基準に並べ替え、とかでできますか?
(私は1つの方法でしか知らないので、どうしても意図する順番になりません。)
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
はい。
ごめんなさい。バグってます。> 4.追加したいIDかを判断する。追加したいのであれば 5、そうでなければ 6 へ。
>5.まず $lines[$a] を書き出し。 で、次に%FORMを整形して書き出し。
>6.$lines[$a]を書き出し。
># 4. 5. 6. は まとめると以下の4行....
> print $line;
>if( $ID == $FORMw{ID} ){
> print LOG "ID=$ID&COUNT=$COUNT&TITLE....
とあるうちの
> print $line;
は
print LOG $line;
の誤りでした。
No.4
- 回答日時:
> しかし、「同じIDがあった場合、それの下に書き込む」ができません。
フラグが必要かと。こんな感じ↓
$insert_line = 挿入したい行;
$flag = 0;
foreach (読み込んだログ) {
$current_line = $_;
if ($flag == 0) {IDが一致したら$flag = 1;}
if ($flag == 1) {IDが異なったら$insert_lineをログに書き込み; $flag = 2;}
$current_lineをログに書き込み;
}
if ($flag < 2) {$insert_lineをログに書き込み;}
終了;
みなさま回答ありがとうございました。
自分なりのやり方でなんとかできました。
(大分遠回りのやり方ですが、こうでもしないと自分でわからないので)
方法としては、
●IDが一致したものの前までのログ
●IDが一致したものの親ログ
●IDが同じ書き込み(実際の入力)
●それ以降のログ
にわけ、それぞれを書き込むようにしました。
No.3
- 回答日時:
全体的なソースが出てきて全容がつかめそうなのですが、何がしたいかふめいでつ。
何処と聞かれれば全体ですと答えるしか・・・私が全部書き直していいのですか?
先にも書きましたが、流れに沿ってもう少し具体的に書きましょう・・・。
1.ログファイルを全部 @lines に読み出す。
open(LOG,"log.log");
@lines = <LOG>;
close(LOG);
2.読み出しに開いたファイルを閉じて書き込み用に開ける( ">>" では無く ">" です。)
open(LOG,">log.log");
2.foreach などで @lines を順番に以下のことを行なう
foreach $line(@lines){ #foreach1
3.$lines[$a] などに対して各データに分ける( split ~ ってやつ。)
foreach(split(/&/,$line)){ #foreach2
> ($keyw,$valuew) = split(/=/,$_);
> $FORMw{$keyw} = $valuew;
> } #foreach2
#↑一応こんなのでいいはずだが <> や タブ なんかで分けてると
#ココがもっと楽。
4.追加したいIDかを判断する。追加したいのであれば 5、そうでなければ 6 へ。
5.まず $lines[$a] を書き出し。 で、次に%FORMを整形して書き出し。
6.$lines[$a]を書き出し。
# 4. 5. 6. は まとめると以下の4行....
print $line;
if( $ID == $FORMw{ID} ){
print LOG "ID=$ID&COUNT=$COUNT&TITLE....
}
} #foreach1
clsoe(LOG);
##########################################
・・・大分変わっちゃいました。上記ソースは当然動作未確認...
で、示していただいたソースの問題点は以下のとおり。
1. if($ID=.... の扱い。 if で囲まれた中にしか print 命令が無い
2. split で & や = を切っているが一考の余地あり。データのフォーマットを再考してください。
3. last が不明。 for の中の if の中の for といったネストが微妙。
#####################################
で、今になって誤解が発覚したのだが、
追加したデータって $ID とか $COUNT だったのな。
%FORMw だと思ってた。
なもんで、以前までの投稿は微妙に間違ってた。すまぬ。
回答ありがとうございます。
ログファイルを開く時に>(書き込み)で開くと、どうしてもすべてのログが消えてしまうのですが。
それとご指摘の通り、ログファイルを<>で区切るようにしました。
($ID<>$COUNT<>$TITLE…というカンジです。)
これですとどんなカンジになりますか?
今自分でつくった流れとしては
トップページ(新規入力→Aへ。 返信入力→Bへ)
A
フォームを表示。
ログファイルを開き、すべてのIDを調べ、1番大きなIDに1を足したものをIDとしてわりあてる。
ログファイルの中身が空っぽならそのままログファイルへ書き込み。
すでにログファイルの中身があれば、現在入力されたデータ+すべてのログファイルという形で書き込みを行う。
($COUNTはすべて1)
B
返信入力なので、親書き込みのIDをわりあて。
$COUNTは親IDの$COUNTに1を足す。(なので2となる)
ログファイルを開き、同じID(親書き込み)を探す。
同じIDがみつかったらその下の行へ書き込みを行う。
親IDが1番下とは限らないので、真ん中だったり一番下への書き込みとなる。
(返信なので1番上はありえない。)
となってます。
Aはすべてできました。
Bの4行目でひっかかっています。
教えていただいたものを実行してもログが消えてしまいます。
どうぞよろしくお願いします。
No.2
- 回答日時:
どもも。
ログってことですが、何を目的にしているかにもよりますが余りいただけない書式ですな・・・
ファイルに記述する場合は、 form から取るときと違って、& で区切られた各値が前後することは絶対にありませんので。
ID=$ID&COUNT=$COUNT.....
というのは、それはそれで目的があるならいいのですが単にデータを記録するだけなら たとえば <> や , や タブ符で各値を区切って、
$ID<>$COUNT.....
とするほうが良いかもしれません。何かと楽ですす。
で、何が楽かってと、最初の部分でやってる split とか for で回してる部分がもっと効率的に欠けます。
で、話を戻して、追加の方法ですが簡単には以下のようになります。
1.ログファイルを全部 @lines に読み出す。
2.読み出しに開いたファイルを閉じて書き込み用に開ける( ">>" では無く ">" です。)
2.foreach などで @lines を順番に以下のことを行なう
3.$lines[$a] などに対して各データに分ける( split ~ ってやつ。)
4.追加したいIDかを判断する。追加したいのであれば 5、そうでなければ 6 へ。
5.まず $lines[$a] を書き出し。 で、次に%FORMを整形して書き出し。
6.$lines[$a]を書き出し。
見たところ、 $FORMw の書き出しが含まれていませんな。これを"追加"すればいいと思われ。
あと、ログの最初に追加するってのはもっと楽で、全ファイル内容を @lines に読み取ってそこに整形した $FORMw のデータを unshift して、 @lines を書き出すのが一番楽かと。
(seek はめんどくさい...)
まだまだ続いて... 複数値によるソートですが、可能です。が、少々面倒で ハッシュを用いたソートでしょうか。
回答ありがとうございます。
どうにか新規書き込み(ログの一番上に書き込む)はできました。
しかし、「同じIDがあった場合、それの下に書き込む」ができません。
下記のようにしてみたのですが…。
open(FH2,"log.log");
@log2 = <FH2>;
close(FH2);
$gyou = @log2;
for ($w=0;$w<$gyou+1;$w++){
@log3 = split(/&/,$log2[$w]);
foreach(@log3){
($keyw,$valuew) = split(/=/,$_);
$FORMw{$keyw} = $valuew;
}#foreach
if ($ID == $FORMw{'ID'}){
open(FH3,">>log.log");
@loglog2 = <FH3>;
for($r=0;$r<$gyou+1;$r++){
if($r == $w){
print "wは?$w<BR>\n";
print "rは?$r<BR>\n";
print
FH3"ID=$ID&COUNT=$COUNT&TITLE=$TITLE&NAME=$NAME&PASSWORD=$PASSWORD&NAKAMI=$NAKAMI&COLOR=$COLOR&TIME=$TIME&S
EARCHKEY=$SEARCHKEY\n";
#print FH3"$ID<>$COUNT<>$TITLE<>$NAME<>$PASSWORD<>$NAKAMI<>$COLOR<>$TIME<>$SEARCHKEY\n";
close(FH3);
last;
}# if
}#for
last;
:
:
どこを直せばいいのでしょうか?
No.1
- 回答日時:
ぱっと見た感じですが、
おそらく@log2(にデータが入っていて)を分解、
そのIDと今回投稿されたID比較してるのですよね?
いくら途中で振り分けても、
print FH3 ~~
と同じように両方とも書き込んでいるので、
両方とも同じくなるのは当然かと思います。
既に@log2にデータが丸ごと入ってるなら、
それに新しいデータを追加して、
全体を書き込んだ方が処理は楽だと思いますよ。
(新しいデータを途中に埋め込む場合は)
>最新ログを1番上に書き込む、ということをしたいのですができますか?
seek をキーワードに検索してみてください。
>1番目と3番目を基準に並べ替え
これももちろんできますが、結構面倒です(^^;
sort関数を調べてみると色々例がのっています。
ところで、
何回もファイルが重ねて開かれてるような・・
しかもきちんと閉じてないような・・(苦笑)
open~closeとそれにともなうseek/truncateなどや、
ファイルロックについてもう一度確認されてみるといいと思います。
#蛇足ですが、print @sort と print "@sort"
"@sort"はPerlが自動的に半角のスペースをいれるのです。
@data = qw(this is useful);
print "@data"; #this is useful
print @data; #thisisuseful
となります。
(つまり、特別に配慮されているということでしょうか)
なお、$" で変更できます。
回答ありがとうございます。
ちょっと今すぐに全部には答えられないので、さしあたって少しだけ補足させていただきます。
>>最新ログを1番上に書き込む、ということをしたいのですができますか?
>seek をキーワードに検索してみてください。
はい、seek関数に私も行き着きました。
それでつかってみたのですが…どうもちゃんとしてないみたいなんですけど…。
seek(FH3,0,0);
print FH3"ID=$ID&COUNT=$COUNT&TITLE=$TITLE&NAME=$NAME&PASSWORD=$PASSWORD&NAKAMI=$NAKAMI&COLOR=$COLOR&TIME=$TIME&SEARCHKEY=$SEARCHKEY\n";
でログファイルの1番最初に入力される(はず)なんですよね?
1番最後に入力されてしまうのですが…。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- PHP コメント機能に返信欄を矢印で追加したい 1 2022/05/09 21:17
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- MySQL php テーブルを作れない 2 2022/11/17 18:22
- PHP php テーブルが作成できない 1 2022/11/17 23:41
- Access(アクセス) アクセス 有効なフィールド名、または式として認識できませんのエラー 3 2022/08/19 11:53
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- HTML・CSS CSS のみのタブ切り替えについて 1 2023/01/11 16:47
- PHP PHPでユーザー情報を入力して簡易ログイン機能をつくってみたのですが 1 2023/05/29 08:51
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エラーチェック、ファイルに特...
-
cgiのログの書き方
-
perlでcsvファイルを読む(ダブ...
-
Perlで特定行から特定行までを...
-
csvデータの開始行と最終行を全...
-
python renameについて
-
VBAで巨大なファイルの途中から...
-
batファイルでrenameができませ...
-
Perlでのファイル出力における...
-
csvファイルの横方向への改行に...
-
VBAでCSVファイルの特定行を書...
-
Pythonでegrep機能をつかいたい
-
awkスクリプトでダブルクォーテ...
-
csv出力
-
VBAでCSVファイルを途中行まで...
-
VB6.0でDB接続する際に切断時の...
-
ディレクトリ名を取得したい
-
FindFirstFileとFindNextFileで...
-
ファイルの一部を別のファイル...
-
ListBoxのデータを高速でファイ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Perlで特定行から特定行までを...
-
Perlの初心者です。2重ループ...
-
ディレクトリ内のtxtファイル中...
-
Perlで空白行を削除
-
perlでcsvファイルを読む(ダブ...
-
Perlを利用してテキストフ...
-
ファイルの3行目までを出力したい
-
foreachの制御
-
Java CSVファイルをカンマごと...
-
Argument "\\\\n" isn't numeri...
-
エラーチェック、ファイルに特...
-
CSVデータの編集の際の重複チェ...
-
FTP接続時失敗時、接続先名をcs...
-
CSVファイルのデータの行数を取...
-
cgiのログの書き方
-
MATLAB std::exceptionエラー
-
VBAでCSVファイルを途中行まで...
-
awkスクリプトでダブルクォーテ...
-
VBAでCSVファイルの特定行を書...
-
バッチファイルの作り方(CSV→...
おすすめ情報