![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
ウィンドウズ環境でactive perlを利用しています。
あるディレクトリーの中に2000位のファイルが入っており、このファイルを読み込んで置換処理を行うため下記のようなperlを作っています。
1ファイルはおおよそ3000行くらいです。
foreach(<*.html>) {
open(IN_FILE, $_) || die;
open(OUT, ">$_.tmp") || die;
@record=<IN_FILE>;
foreach $record (@record){
$record =~s/aaa/bbb/isg;
}
print OUT @record;
close( IN_FILE);
close( OUT);
rename("$_.tmp", $_) ;
}
当たり前かもわかりませんが、メモリー不足になり処理が中断します。
ディレクトリーの中のファイル数を600程度に少なくすると処理が完了します。
そこで質問なのですが、ディレクトリーの中のファィルを一度に全部読み込まず、1ファイルずつ順次読み込んでいくことはできないでしょうか。
最初の1行目のforeachをwhileに変えたりしたのですがうまくいきません。
対応策あればご教示ください。
No.1ベストアンサー
- 回答日時:
まず、<*.html>が原因かどうかの確認。
@files = <*.html> ;
だけのスクリプトが動作するかどうか。
動作しないようなら、ここでのメモリ不足なので、対策をする。
例えば、opendir, readdir, closedir を使う。
my $dirname = '.' ;
opendir my $dp, $dirname ;
while(my $fname = readdir $dp){
# 今回はカレントディレクトリなので不要だが
# readdirでは名前しか得られないので、実際にopenなどで使うには
# opendirに使ったディレクトリを追加する
my $fullname = $dirname . '/' . $fname
# html以外は対象外
if ( $fname !~ /.*\.html$/ ) {
next ;
}
...
$fname/$fullnameについての処理
...
}
closedir $dp;
動作するようなら、その後の処理が問題。
今のやり方(一時ファイルに出力→リネーム)でやるなら、@record=<IN_FILE>;などと全部取り込まなくても、一行ずつ処理すればいい。
@record=<IN_FILE>;
foreach $record (@record){
$record =~s/aaa/bbb/isg;
}
print OUT @record
→
while(my $record = <IN_FILE>){
$record =~ s/aaa/bbb/isg;
print OUT $record
}
この回答への補足
早速回答いただきありがとうございます。
@files = <*.html> ;は作動しました。
while(my $record = <IN_FILE>){
$record =~ s/aaa/bbb/isg;
print OUT $record;
}
もうまくいきました。本当に有難うございます。
実は多分「opendir, readdir, closedir 」を使うのだろうなと考えていたため、
一時ファイルに出力→リネームの場合に対応する方法があるとは考えてもいませんでした。
質問内容について聞けば全てに応用できると思っていたのですが、応用できないパターンが出てきてしまいました。
新規にファイルを作るパターンもよく利用しておりこちらもメモリー不足で悩んでいます。
こちらもディレクトリーの中に2000位のファイルが入っており、
1ファイルはおおよそ3000行くらいです。
このファィルから特定の情報を抜き出し、一つのファイル(下記の場合はichiran.html)として出力します。
元のファイル一つに対し抜き出した情報は1行しかありませんので出来上がったichiran.htmlは2000行程度のファイルです。
下記のようなperlの場合はどのようにすればいいのでしょうか。
追加で申し訳ありませんがよろしくお願いします。
foreach(<*.html>) {
open(IN_FILE, $_) ;
@record=<IN_FILE>;
foreach $item (@record){
#項目
if ($item=~ /.*<[^>]*Title\">([^>]*)<.*/si) {
$koumoku= "$1";
$item= "";
}
#原価
elsif ($item=~ /.*<[^>]*Price\">([^>]*)<.*/si) {
$kakaku="$1";
$item= "<tr><td>$koumoku<\/td><td>$kakaku<\/td><\/tr>
}
else {
$item="" ;
}
}
@total = (@total, @record);
}
close( IN_FILE);
$out_file="./ichiran.html";
open(OUT_FILE, ">>$out_file") ;
print OUT_FILE @total;
close( OUT_FILE);
No.3
- 回答日時:
「元のファイル一つに対し抜き出した情報は1行しかありません」ということがわかっているなら, わざわざ巨大な配列を作らなくていいのでは?
もちろん「ファイルを一度に読み込む」ことが必要な処理だとも思えない.
push なんてのもあるけど.
何度もありがとうございます。
わかりにくい書き方で申し訳ありません。
個々のファイル内の抜き出すデーターは2行にわかれているものもあり、一旦全部読み込み整理しています。
ただしディレクトリーの中のファイルをすべて読み込む必要はなく、ここを何とかしたかったのですが、同じ物を何度も読み込んでしまいうまくいきませんでした。
教えていただいた内容を比べると
if ( $fname !~ /.*\.html$/ ) {
next ;
}
の部分が不足していました。
お陰様で、ディレクトリーの中のファイルを1つずつ読み込むことができるようになり、全て解決しました。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- C言語・C++・C# C# で、あるフォルダー内にあるすべてのテキストファイルを別のフォルダーにコピーする。 4 2022/11/21 13:23
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
- その他(プログラミング・Web制作) セレクトボックスで選択された値をコントローラーで使用したい 2 2022/07/26 16:41
- Perl Perlで特定文字列から特定文字列までを抜き出したい 4 2022/04/02 14:24
- Visual Basic(VBA) vbaの構文の修正相談(xmlファイルを順に開いてコピペ作業) 1 2023/04/22 01:18
- Perl perlのflock関数でロックをかけたままopen関数で何度もファイルを開きなおすことはできますか 3 2023/05/01 22:25
- その他(プログラミング・Web制作) Pythonを勉強しています。 5 2023/08/25 09:51
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAでCSVファイルを途中行まで...
-
VBAでCSVファイルの特定行を書...
-
エクセルVBA コードが同じでも...
-
ExcelをCSV書き出す場合のシー...
-
Javaで同一のファイルを読み込...
-
VBAで巨大なファイルの途中から...
-
DBMとテキストファイルのどちら...
-
ファイルのアップロード方法(Perl)
-
2つのCSVファイルをマッチング
-
Perlの質問:行と列を入れ替え...
-
CGI(Perl)でWeb上から作成...
-
Excelファイルのデータを入力し...
-
JavaでCSVファイルを高速に読む...
-
perlで、後ろの行を読んで、前...
-
VB6.0でDB接続する際に切断時の...
-
ファイルからある文字列の個数...
-
datファイルってなんですか?
-
ファイル内の日付から1週間前...
-
1ファイルずつ読み込みたい
-
タブの色を変更する方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでCSVファイルを途中行まで...
-
VBAで巨大なファイルの途中から...
-
ExcelをCSV書き出す場合のシー...
-
VBAでCSVファイルの特定行を書...
-
openした後、closeしないでプロ...
-
ReadLineでの読み出し行を指定する
-
エクセルVBA コードが同じでも...
-
csvファイル改行コードの置換に...
-
Perlの変数に文字数制限(容量...
-
perlにて2つのファイル比較
-
C言語でのファイルのデータ更...
-
JavaでCSVファイルを高速に読む...
-
VB6.0でDB接続する際に切断時の...
-
MATLAB グローバル変数の宣言
-
alarmのタイムアウト後の処理で...
-
DBMとテキストファイルのどちら...
-
perlで、後ろの行を読んで、前...
-
拡張子 ”log” と ” dat” の違い
-
5行おきに5行ずつ抽出するに...
-
テキストデータから指定した1...
おすすめ情報