ファイル内の任意の文字列(バイナリOK)を探索

Windowsのファイル内検索システムがクソすぎるので急ぎで作った。

my $search = "文字列";


my $MIN_BUFFER_SIZE = 4096;

foreach my $file (<*>){
	if(! -f $file){ next; }
	print "$file\n";
	open my $FH, "<", $file || die 'cant open file';
	binmode($FH);
	my $buf;
	my $data;
	my $totalread = 0;
	my $readlength = 0;
	
	my $searchlength = length($search);
	my $bufferlength = $searchlength  > $MIN_BUFFER_SIZE ? $searchlength  : $MIN_BUFFER_SIZE;
	
	while($readlength = read($FH, $buf, $bufferlength)){
		$data .= $buf;
		my $pos = 0;
		while(($pos = index($data, $search, $pos)) != -1){
			printf("\toffset:%d\n", $totalread + $pos);
			$pos += 1;
		}
		$data = substr($data,-length($search));
		$totalread  += $readlength; 
	}
	close $FH;
}

カレントディレクトリに放り込んで使うイメージ。
バイナリで探索する場合は\x00みたいにします。
同じ文字列が2回hitすることもあるけど、取りこぼしはないし、使う分には困らないので仕様です。