私はパフォーマンスに大きな問題に直面しています。約600のサブディレクトリを持つ巨大なディレクトリ(30 GB)に存在するファイル内のキーワードを検索する必要があります(これには、内部に多くのサブディレクトリがあります)。
現在、サブディレクトリを 50 個のテキスト ファイルに分割しているため、各ファイルは 12 個のサブ ディレクトリ名を取得し、50 個のプロセスすべてを実行します。
my $pm = Parallel::ForkManager->new($lines);
# Forks and returns the pid for the child:
my $pid = $pm->start and next;
# we are now in the child process
ucm5 ("-iinput.txt","-f$data"); - here $data will be text file names(text1,text2...text50)
--input.txt will have the multiple search keywords(hi , hello)
$pm->finish; # Terminates the child process
#!/usr/bin/perl
sub ucm5 {
local @ARGV = @_;
use strict;
use warnings;
use File::Find;
use Getopt::Std;
#getting the input parameters
getopts('i:f:');
our($opt_i, $opt_f);
my $searchKeyword = $opt_i; #Search keyword file.
my $intfSplit = $opt_f; #split file
my $path = "C:/"; #source directory
my $searchString; #search keyword
open FH, ">>log.txt"; #open the log file to write
print FH "$intfSplit ". "started at ".(localtime)."\n"; #write the log file
open (FILE,$intfSplit); #open the split file to read
while(<FILE>){
my $intf= $_; #setting the interface to intf
chomp($intf);
my $dir = $path.$intf;
chomp($dir);
print "$dir \n";
open(INP,$searchKeyword); #open the search keyword file to read
while (<INP>){
$searchString =$_; #setting the search keyword to string
chomp($searchString);
print "$searchString \n";
#open my $out, ">", "vob$intfSplit.txt" or die $!; #open the vobintfSplit_* file to write
open my $out, ">", "vob$intfSplit.txt" or die $!;
#calling subroutine printFile to find and print the path of element
#the subroutine will search for the keyword and print the path if keyword is exist in file.
my $printFile = sub {
my $element = $_;
if(-f $element && $element =~ /\.*$/){
open my $in, "<", $element or die $!;
while(<$in>) {
if (/\Q$searchString\E/) {
my $last_update_time = (stat($element))[9];
my $timestamp = localtime($last_update_time);
print $out "$File::Find::name". " $element"." $timestamp". " $searchString\n";
last;
}
}
}
};
find(\&$printFile,$dir);
}
}
print FH "$intfSplit ". "ended at ".(localtime)."\n"; #write the log file
}
1;
コードは少し混乱するかもしれません。何をしているのかを説明します。最初の while ループでは、サブディレクトリを含むテキスト ファイルを開き、その内部では、別の while ループで検索語 (こんにちは、こんにちは) を含むテキスト ファイルを開きます。その file::find 内で、サブディレクトリ内のキーワードを検索するために呼び出されます。
ここで、最初のサブディレクトリに移動して最初のキーワード (HI) を検索し、一度完了すると、同じディレクトリに移動して次のキーワード (Hello) を検索します。これは、同じディレクトリを 2 回読み取ることを意味します。
しかし、最初の読み取り時間自体で両方のキーワードを検索したいので、多くの時間を節約できます。私の出力には、パス、ファイル名、検索語が必要です。
例
C:/aims/if/sp/abcd.sql abcd.sql こんにちは
C:/aims/if/sp/abcd.sql abcd.sql こんにちは
この問題で私を助けてください。並列処理とスレッド以外に、複数のキーワードを使用して 600 のサブディレクトリすべてを検索するより良い方法はありますか。