特定の文字列のある行を削除するには??

[上に] [前に] [次に]
ポチ 1999/12/04(土) 21:30:09
ログファイルから特定の文字列(■■■)を削除する処理なら
-------------------------
#!/usr/bin/perl
$file = "./log.txt";
open DAT, "$file" ;
@dat=<DAT>;
@list = grep m/■■■/, @dat;
foreach $i (@list){
$i =~ s/■■■(.+)/$1/g;
push (@var,$i);
}
print DAT @var
-------------------------
でうまくいったのですが
■■■の入った行を削除していくにはどうしたらいいのでしょうか??

1999/12/05(日) 00:20:00
open(DAT,"+< ./log.txt");
flock(DAT, 2);
while(<DAT>){
push(@lines,$_);
}
foreach $line (@lines) {
if($line !~/■■■/) {
push(@new,$line);
}
}
truncate(DAT,0);
seek(DAT,0,0);
print DAT @new;
close(DAT);

こういう事では無い?

ふじ 1999/12/05(日) 00:25:37
#!/usr/bin/perl
$file = "./log.txt";
open DAT, "$file" ;
@dat=<DAT>;
@dat = grep !m/■■■/, @dat;  # ■■■ を含まない行だけ取り出す
print DAT @dat;

一気に配列に読み込むならこんな感じ。ですが、
(どんなログファイルを処理するのかは分かりませんが)
ファイルが大きい場合、一気に配列に読み込むのはやめた方が身の為です。
一行ずつ読んで、

while(<DAT>){
    print $_ unless /■■■/;
}

等とする方がお勧め。

J.Naka 1999/12/05(日) 03:08:32
■■■の入った行を削除します。
-----------------------
#!/usr/bin/perl
$file = "./log.txt";
open DAT, "$file" ;
while(<DAT>){
if($_ =! /■■■/){
push (@var,$_);
}
}
close(DAT);
-----------------------
行削除だけならこれでいいんでないの?
データーを触る回数はできるだけ少ない方が処理速度上がりますよ。
元ファイルが馬鹿でかくて一度に配列に読み込むのヤバイなら上のループの適当なところで配列データを掃き出す(ファイルなど)して配列リセットしたら良いかも。

 え〜、配列に一気読みが良くない理由が良く分からないのですが、これは仮想記憶を普通に使っていれば問題起きることではないと思うので、言語のメモリ使用が単にまずからでしょうか?
 とにかく、一気読み、つまりメモリの連続確保がまずいのならば、配列に取り込み中にある程度のところで、データを別変数に移動すれば連続確保を避けられる事になるので問題解決ということになるのでしょうか?
#何故仮想記憶のあるOS上でメモリ問題がおきるんだぁ? と、思ってしまう(^^;

ふじ 1999/12/05(日) 03:54:59
>#何故仮想記憶のあるOS上でメモリ問題がおきるんだぁ? と、思ってしまう(^^;
原理的には問題が起きないかも知れませんけど...
複数のプロセスが資源を共用している ISP のサーバ上で不用意に
メモリを消費すると、他の人にも迷惑掛けますし、気を使った方がいいです。

御自分の機械の実メモリ以上のサイズのファイルを
配列に一度に読み込んで処理する、というスクリプトを書いて
テストをなさってみては。
# しかもそれを一度に複数起動、とか。

S-pore [HomePage] 1999/12/05(日) 09:49:34
仮想記憶があるといっても,実際スワップが頻繁に発生すると
極端に速度低下しますからね・・・。
そういうことではないでしょうか?

J.Naka 1999/12/05(日) 11:49:45
う〜と、なんか元題から離れる感じで後ろ髪引かれるんですが(^^;

 マルチタスク&マルチユーザー&仮想記憶のOS上の保護機構最上位にあるアプリケーションの物理メモリ確保の実際は、まず確保単位がOS種にもよりますが、数キロバイト単位ですよね。
 つまりこれ以下の細切れ処理をアプリ側がOS資源を考慮するつもりでやっても、意味が無いという事になるのではないでしょうか?無意味というよりも、メモリ操作が煩雑に発生するという意味で帰ってOS負担になるのではないでしょうか? さらには、OSの物理メモリ操作とアプリ側が使用するメモリとは間にキャッシュなどが入るため、実際のOS負担がどの程度になるかは非常に予想難しい&無意味に帰するのではないでしょうか?
 アプリ側が考慮出来るのは、OSレベル&CPUレベルのページング単位を越えるメモリ使用作業はOSに負担を掛ける度合いが大きい可能性があるかもしないということぐらいではないでしょうか。インテルx86系CPUのページングは4キロが多いので、これが大体の目安かなと。
闇雲に細切れ処理しろというは先人が構築したコンピューターシステムを無視する文明の機器を活用しないもったない事と思う。 

J.Naka 1999/12/05(日) 11:59:32
>仮想記憶があるといっても,実際スワップが頻繁に発生すると
>極端に速度低下しますからね・・・。

 スワップ発生によるシステム全体の処理能力低下はシステム側が対処する問題、それをコナス事を目標にOSは進化してしてきたと思う。ユーザーアプリはユーザーのロジックに専念しその環境を提供するのに専念(進化)するのがOS。そして全体で強固でユーザーフレンドリーなシステムとなる。
 システムの各オブジェクトは自分の機能に専念すれば良い、そういう事ではないかと思うのだが。

J.Naka 1999/12/05(日) 12:09:12
あっ、あかん(笑)。単なる理想論だすね(^^;;;

ふじ 1999/12/05(日) 16:41:36
本題とそれちゃって済みません。

>実際のOS負担がどの程度になるかは非常に予想難しい&無意味に帰するのではないで
>しょうか?
確かに、数KB〜数MB程度のファイルサイズで、一行ずつ読み込むのと
配列に一気に読むのとでどっちが OS に負担を書けるか、ということに
ついては、確かに難しい話です。

../199906/99060273.htm
こんな実験もしてみたことがありますが。

ただ、読み込むファイルが確実に小さい(それほど大きくない)
ことが分かっていればともかく、大きさのチェックもしないで
いきなり配列にブチ込むのは...
仮に、それが他のプロセスも書き込むファイルで、滅茶苦茶大きく
なってたら、どうします?
# 大規模なサーバの access.log を読み込んだりとか。

>スワップ発生によるシステム全体の処理能力低下はシステム側が対処する問題
でも実際無駄づかいすると迷惑なんだってば。
(スラッシング、と言う現象に陥るの)
http://www.ascii.co.jp/ghelp/5/000541.html

J.Naka 1999/12/05(日) 18:09:52
>「負荷を小さくするには?」../199906/99060273.htm

見ました。
面白いですね。NTのページング4Kbより遥かに小さい、1.26kbのサイズでも1行処理より時間かかるんですね。要因は色々を推測できそうですがが、取りあえず結論としてNTでは動的メモリバッファは小さい方が処理が軽いって事なんですね。
ところで、リザルトの wallclock ってどういう事ですか?(^^;
それと、テスト時のメモリ空き状況とかのシステム状態はどんな感じだったのでしょうか?他のサーバー(UNIX)の場合はどうなるんでしょうか?

ポチ 1999/12/05(日) 22:58:44
あうあう 既に解決ボタン押す権利 私にはなさげなので
あとの処置お願いします(笑)

返信ありがとうございます
質問の件はうまくいきました

とほほ 1999/12/06(月) 00:13:31
[[解決]]
最初の質問が解決していれば、(というより、タイトルに書かれた
質問が解決していれば、)解決マークです。
・・・ということで、ぷち。

[上に] [前に] [次に]