4

テキストの置き換えが必要なファイルが約 400,000 個あります。

次のPerlスクリプトを試しました:

@files = <*.html>;

foreach $file (@files) {
    `perl -0777 -i -pe 's{<div[^>]+?id="user-info"[^>]*>.*?</div>}{}gsmi;' $file`;

    `perl -0777 -i -pe 's{<div[^>]+?class="generic"[^>]*>[^\s]*<small>[^\s]*Author.*?</div>.*?</div>.*?</div>.*?</div>.*?</div>}{}gsmi;' $file`;

    `perl -0777 -i -pe 's{<script[^>]+?src="javascript.*?"[^>]*>.*?</script>}{}gsmi;' $file`;

    `perl -p -i -e 's/.css.html/.css/g;' $file`;
}

Perl についての深い知識はありませんが、スクリプトの実行が遅すぎます (1 日あたり約 180 ファイルしか更新されません)。

それをスピードアップする方法はありますか?

前もって感謝します!

PS:少数のファイルでテストしたところ、パフォーマンスがはるかに優れていることがわかりました...

4

2 に答える 2

8

perl から perl を呼び出すと、すべての作業を 1 つのプロセスで実行するよりも常に遅くなります。したがって、解決策は次のようになります

perl -i -pe 'BEGIN { undef $/ }
             s{<div[^>]+?id="user-info"[^>]*>.*?</div>}{}gsmi;
             s{<div[^>]+?class="generic"[^>]*>[^\s]*<small>[^\s]*Author.*?</div>.*?</div>.*?</div>.*?</div>.*?</div>}{}gsmi;
             s{<script[^>]+?src="javascript.*?"[^>]*>.*?</script>}{}gsmi;
             s/.css.html/.css/g;
    ' *.html
于 2012-11-30T21:06:14.497 に答える
7

まず、400,000 個のファイル名をメモリにロードすると、メモリが消費されます。たとえば、次のようにして、ファイルリストを簡単に反復処理できます。

  • File::Find
  • opendir+ while (readdir($dh)) (リスト全体をロードしません)

第 2 に、バッククォートを使用すると、シェルで新しいプロセスが生成されますが、これは非常に効果的ではありません。ファイルを普通に開いて丸呑みし、同じファイル名に再印刷するだけです。例えば

while (my $file = readdir($dh)) {
    open my $fh, "<", $file or die $!;
    local $/;
    my $text = <$fh>;                # slurp file
    $text =~ s/....//g;              # do your substitutions
    open $fh, ">", $file or die $!;
    print $fh $text;                 # overwrite file, same as -i switch does
}

最後に..正規表現を使用してhtmlを編集することは理想的ではありません。あなたのケースではうまくいくかもしれませんが、html パーサーの学習に時間を費やす価値があるかもしれません。この特定のケースにどれだけ適しているかはわかりませんが、コードをより安定させるために検討する価値があるかもしれません.

于 2012-11-30T21:10:44.003 に答える