我有一个大尺寸的文本文件。(大约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
有关如何定义空白的详细信息,请参阅 参考资料。
任何剩余的参数都被视为要搜索的文件名。
为了避免一次将整个输入文件加载到内存中,该脚本一次扫描一个输入“块”。为了避免丢失任何输入,它会增加语句$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
最后,这些脚本都没有经过充分测试。我既没有巨大的文本文件可供搜索,也没有巨大的“句子”可供搜索。因此,它们作为一个可能的正确方向的近似指针提供,而不是作为完整的工作代码。