ここで教えてもらってログファイルの書き方(挿入のようなカンジで)をやってみたんですが、どうしても思い通りの動きをしません。
希望としては、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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Perlで特定行から特定行までを...
-
excel→txtファイル作成時、セル...
-
VBAで巨大なファイルの途中から...
-
ifstream/ofstream について
-
chdirがうまくできない
-
VBAでCSVファイルの特定行を書...
-
ファイル名を複数個配列で確保...
-
fopenでディレクトリ内の全ファ...
-
ReadLineでの読み出し行を指定する
-
C言語で特定の行を抽出する方法...
-
MySQLにバイナリデータを正常に...
-
XML::Parserの parsefileの結果...
-
パスから最後のディレクトリだ...
-
Perl 特定のフォルダ以外削除
-
大容量テキストファイルから任...
-
Perl で syntax error
-
ExcelをCSV書き出す場合のシー...
-
空白文字 \\f と\\v の違いに...
-
perlのエディタでおすすめを教...
-
JSP URLに表示される拡張子 .jsp
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Perlで特定行から特定行までを...
-
Argument "\\\\n" isn't numeri...
-
Perlの初心者です。2重ループ...
-
foreachの制御
-
Perlで空白行を削除
-
配列の値の操作について教えて...
-
テキストファイルへ行指定での...
-
csvデータをテーブル表示させる
-
データベースを使わず、テキス...
-
Perlを利用してテキストフ...
-
pythonでの実績データの処理プ...
-
perlでcsvファイルを読む(ダブ...
-
郵便番号辞書のアップデート手...
-
perl:パターンマッチを使ったif...
-
perlでファイルの比較
-
エラーチェック、ファイルに特...
-
VBAでCSVファイルを途中行まで...
-
エクセルVBA コードが同じでも...
-
VBAでCSVファイルの特定行を書...
-
ExcelをCSV書き出す場合のシー...
おすすめ情報