- ベストアンサー
perlでテキストファイルを上向きに検索する方法とは?
- perlでテキストファイルを加工する際に、上向きに検索する方法を教えてください。
- 特定の語句が出現した時に、そのブロックの先頭から抜き出す方法を知りたいです。
- テキストファイルを「check.txt」と「normal.txt」に分けて保存する方法についても知りたいです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
> my $tmp='tmp.dat'; > (中略) > print NEWFILE $tmp; NEWFILEに文字列'tmp.dat'を出力してるみたいだけど、 これが出力したい内容なのですか? > open(NEWFILE, '>> $tmp') or die "$!"; > (中略) > if ($flg==1){ > open(NEWFILE, '>> check.dat') or die "$!"; これではwhileループ内でNEWFILEに対してopenが2回連続で行われてしまいます。 これでは一回目のopenで得られたファイルハンドルを見失ってしまいますよ。 また、 > if ($line eq "head") が成立するときはcloseも2回行われてしまいます。 そもそもループ内で同じファイルのopen/closeを繰り返すのは非効率だからやめたほうが良い。 今回の場合はループ前で必要なファイルを全部openして、 最後に全部closeすれば問題ないはず。 (当たり前だけどファイルハンドルの名前は全部違うものにしてね。) あと、$lineには改行コードが含まれるので > if ( $line eq "#check line#" ){$flg=1;} > if ($line eq "head"){ これらのif文が成立することはないと思います。 改行コードが含まれていても大丈夫なように書いてください。 (あらかじめchompするとか、部分一致で検出するとか、改行を含む文字列と比較するとか。) > フラグの設定の仕方、蓄積の方法について教えていただけますでしょうか フラグの設定はそんな感じでよいとして、 蓄積は適当な変数(下の例では$buf)に$lineの内容をどんどん足していけばよい。 で、フラグをクリアするタイミングで$bufを空にする。 my $buf = ""; while (my $line = <FILE>) { $buf .= $line; # 略 if ($line =~ m/^head/){ if($flg==1){ #check.txtに$bufを出力 }else{ #normal.txtに$bufを出力 } $flg=0; $buf = ""; #$bufを空に } } あとheadを見つけたときだけじゃなくて、 最終行に到達したときもファイル出力する必要がないですか?
その他の回答 (1)
- Werner
- ベストアンサー率53% (395/735)
いや、さかのぼる必要なんて無いでしょう。 1行ずつ読むときにその内容を蓄積しておいて、 ブロックの最後に来たときに一気に出力すればよい。 で、出力後はフラグと一緒に蓄積した内容をクリアする。
補足
すみません、初心者なもので現在のスクリプトは以下のようになっています。 my $tmp='tmp.dat'; my $flg=0; open(FILE, 'sample.txt') or die "$!"; while (my $line = <FILE>) { open(NEWFILE, '>> $tmp') or die "$!"; print NEWFILE $line; if ( $line eq "#check line#" ){$flg=1;} if ($flg==1){ open(NEWFILE, '>> check.dat') or die "$!"; print NEWFILE $tmp; close (NEWFILE); } else{ open(NEWFILE, '>> normal.dat') or die "$!"; print NEWFILE $tmp; close (NEWFILE); } if ($line eq "head"){ $flg=0; close (NEWFILE); } } close(FILE); フラグの設定の仕方、蓄積の方法について教えていただけますでしょうか
お礼
詳しい回答どうもありがとうございました!最終行に来たときの記述を追加し、うまくいきました。本当にありがとうございました。