大きなサイズのテキストファイルがあります。 (約2GB)
電話するA.txt
知りたいです。A.txtファイルに次のものが含まれています文章欲しい(サイズ文章1Byte~500MB)
また、文章含まれるA.txt、バイトに含まれる位置を知りたいです。
答え1
#!/usr/bin/perl -w
use strict;
my $re=shift;
$re =~ s/[[:blank:]]+/\\s+/g;#/this comment only exists to fix SEs perl highlighting
my $blocksize = 100000;
my $filesize;
foreach my $file (@ARGV) {
open(F,"<",$file) || die "couldn't open '$file': $!\n";
$filesize=(stat($file))[7];
my @matches=();
for (my $i = 0; $i <= $filesize; $i+=$blocksize-(length($re))) {
seek(F,$i,0);
read F,$_,$blocksize;
@matches=(m/$re/gmo);
print join("\n",@matches), "\n" if (@matches);
};
close(F);
};
たとえば、別の名前で保存してpuregyu.pl
実行可能にし、chmod +x puregyu.pl
次のように実行します。
./puregyu.pl 'my sentence' a.txt
スクリプトは最初の引数(検索文字列またはパターン)を取り、すべてのスペース[[:blank:]]
(スペースやタブなど)を(スペース、タブ、改行、フォームフィードを含むすべてのスペース)に変更して、複数行にまたがって\s*
いる場合でも文が一致させる。man perlrecharclass
スペースを定義する方法の詳細については、参考資料を参照してください。
残りの引数は検索するファイル名として扱われます。
入力ファイル全体が一度にメモリにロードされるのを防ぐために、スクリプトは入力「チャンク」を一度に1つずつ検索します。入力損失を防ぐために、)の代わりにステートメント$i
()で使用されるオフセット変数を増やします。read
($blocksize - length($re)
$blocksize
ブロックサイズを1000000に設定して、一度に100KiBを読み込みます。テストするのに十分な大きさのテキストファイルがないため、最高のパフォーマンスを得るために調整する必要があります。
注:一致のバイト位置を取得することは、今できる時間よりも多くの作業です。他の人が助けることができます。
複数行の「文」を一致させるには、次の方がうまくいきます。最初の引数として文字列の代わりにファイル名を指定できます。その後、ファイル全体を飲み込んで正規表現に変換します。
#!/usr/bin/perl -w
use strict;
use File::Slurp;
my $re = read_file(shift,chomp=>1);
$re=~s/[[:blank:]]+/\\s+/gm;#/this comment only exists to fix SEs perl highlighting
my $blocksize = length($re)*5;
my $filesize;
foreach my $file (@ARGV) {
open(F,"<",$file) || die "couldn't open '$file': $!\n";
$filesize=(stat($file))[7];
my @matches=();
for (my $i = 0; $i <= $filesize; $i+=$blocksize-(length($re))) {
seek(F,$i,0);
read F,$_,$blocksize;
@matches=(m/$re/gmo);
print join("\n",@matches), "\n" if (@matches);
};
close(F);
};
たとえば、別の名前で保存してpuregyu2.pl
実行可能にし、chmod +x puregyu2.pl
次のように実行します。
./puregyu2.pl searchfile.txt a.txt
最後に、これらのスクリプトのどれも完全にテストされていません。検索する大きなテキストファイルもなく、検索する大きな「文章」もありません。したがって、完全な作業コードではなく、可能な正しい方向へのおおよそのポインタとして提供されます。