dポイントプレゼントキャンペーン実施中!

やりたいことは、"ファイルAを読み取り、その内容に処理を施したものをファイルBに書き込むという処理"です。
その上で、"ファイルBに書き込んだ内容を書き込みと同時に読み取り、
その上である条件にマッチした文を書き換える"といったことを実現したいです。
もともとのファイルの容量が非常に大きいので、何度もループを使うといったことはなるべく避けたいため、
ファイルBの書き込み・読み込み・書き換えを同時に行いたいのですが、
そもそもそういったことは可能なのでしょうか。

※また、もともとのファイルの容量が非常に大きいので配列を使わず行う、
ということが前提条件としてあります。

現在のスクリプトの簡略化したものが以下となります。

open LOGFILE,"< /○○/ファイルA" || die("die");
open NEWLOG,"+< /△△/ファイルB" || die("die");
$new = <NEWLOG>;
while($yomitori = <LOGFILE>){

if(ある条件1){

print NEWLOG "$kakikomi\n";

}
if(ある条件2){
ファイルBの書き換えの処理
$new =~s/\n/ $kakikae\n/;
print NEWLOG "$new";
}
}
close(NEWLOG);
close(LOGFILE);

上記スクリプトで、ファイルAからファイルBへの書き込み、ファイルBの読み取りまではできておりますが、
ファイルBの書き換えは実現しておりません。

以上、お詳しい方がいらっしゃいましたら宜しくお願い致します。

質問者からの補足コメント

  • 回答ありがとうございます!
    処理の説明不足すみません。。
    ログの編集なのですが、以下のようなものになっています。

    <ファイルA>
    処理Aのうちの動作1
    処理Bのうちの動作1
    処理Bのうちの動作2
    処理Aのうちの動作2
    処理Cのうちの動作1
    処理Bのうちの動作3
    処理Aのうちの動作3
    処理Cのうちの動作2



    上記のように、ある処理は複数の動作で成り立っており、各動作に法則性はありません。
    各処理の各動作を処理毎にまとめる動きを実現したいです。
    イメージとして以下のようなログです。

    <ファイルB>
    処理A 動作1 動作2 動作3
    処理B 動作1 動作2 動作3
    処理C 動作1 動作2 動作3
    処理D 動作1 動作2 動作3



    そこで第一段階で
    処理A 
    処理B 
    処理C 




    第二段階で
    処理A 動作を付加(置換)
    処理B 
    処理C 


    のようにしています。

    No.1の回答に寄せられた補足コメントです。 補足日時:2015/04/29 17:01
  • 一時ファイルを作るやり方で探ってみます。
    と同時に、各処理に各動作を付加する回数分だけ一時ファイルを作成する必要があるのかも?と思っており、ログの処理数は膨大なものになっているため現実的ではない?とも思っております。
    当方初心者なもので的外れであればスミマセン。。
    ロジックを練り直したいと思います。

      補足日時:2015/04/29 17:08

A 回答 (3件)

補足読みました。


そういうことなら、処理毎にログをまとめるのがいいでしょう。


ファイルAをそのまま読みこむのではなく、予め処理毎に分割、あるいは、並び換えたものを読み込むのはどうでしょうか?

UNIX系のコマンドが使える環境なら、 sort や grep で処理毎にまとめて、それをパイプラインで読み込む、等
    • good
    • 0
この回答へのお礼

一時ファイルを間に挟み、希望するログファイルに近いファイル作成に成功しました。
あとは、ちょっとした修正と、処理速度(現状、希望する速度には程遠いので。。)を上げていきます。
grepによりログが重複しないようにはしておりますが、sortをうまく使えておりませんので
どう有効活用できるか煮詰めたいと思います。
ありがとうございました!

お礼日時:2015/04/30 19:38

>やりたいことは、"ファイルAを読み取り、その内容に処理を施したものをファイルBに書き込むという処理"です。


>その上で、"ファイルBに書き込んだ内容を書き込みと同時に読み取り、
ちょっと意味が分からないのですが、Aを加工してBに保存したあと、またBを読み込む必要があるんですか?

非常に大きいファイルがどの程度なのかと、
一番大事なのは、処理をしなければならないスパンがどの程度なのかですね。
ファイルの大部分を読み込まないと処理が出来ないのか、小さな1行程度に分けられていて、
1行あればそれで処理と判断が付くのか。

大きいファイルと言っても、
100M程度大きさなら、読み込み用、中間処理用、書き込み用と3つに分裂させてもメモリ消費量は300M程度で、たぶんですが今開いてるブラウザのほうが重いですね。
実際にはどの程度のファイルなのかは分かりませんけども。

それにどうせ、バッファはフラッシュしないと、どんどんたまって行きます。
(実際に出力するのはことが終わったあとに一気におこなわれ、当然出力すべき全ログはメモリに記憶されます)
フラッシュしてもバグの元(ファイルを壊す元)なのでやらないほうがいいだろうと思いますけど。

とりあえず、
while (<IN>){}
の処理は見た目どおり1行づつ読み捨てているので、
適度に改行が入ってるファイルなら、読み込みによる影響でメモリは消費しないものと思われます。


ファイルAとファイルBの関係がよく分からないのですが、
両方のファイルを併せて処理手順が書かれているんでしょうか?
そしてその処理によって、ファイルBを書き換えるんでしょうか?
だとするならば、ファイルはもう一つ用意するのが普通です。
Bをいろいろなことに使いすぎじゃないでしょうか。
    • good
    • 0
この回答へのお礼

>一番大事なのは、処理をしなければならないスパンがどの程度なのかですね。
ファイルAは最大で5~600MB程度だと予測しておりますが、1分ごとにファイルAを処理し、ファイルBを少しづつ作成していく処理を考えております。

容量の大きいファイルも扱い方次第ということを教えていただきありがとうございます!

>Bをいろいろなことに使いすぎじゃないでしょうか。
そうですよね、柔軟に考えることができませんでした。。もっと経験をつみがんばります。

いろいろ丁寧に教えていただきありがとうございます!

お礼日時:2015/04/30 19:43

Bに書く前に、文字列を操作すればいいのでは?



if(ある条件1){
 #ここでは書き込まず
 #print NEWLOG "$kakikomi\n";

 if(ある条件2){
  # 内容を変更
  $kakikomi =~s/\n/ $kakikae\n/;
 }
# 変更したものを書き込む
 print NEWLOG "$kakikomi";
}



具体的な条件が書いてないので、このまま使えるかどうかはわかりませんが。


あるいは、一旦 一時ファイルを経由させるとか
A → 一時ファイル → B
この回答への補足あり
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます!

お礼日時:2015/04/29 17:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!