Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我的perl比较脚本在运行大型txt文件时失败,任何人都能帮助提高性能吗_Perl - Fatal编程技术网

我的perl比较脚本在运行大型txt文件时失败,任何人都能帮助提高性能吗

我的perl比较脚本在运行大型txt文件时失败,任何人都能帮助提高性能吗,perl,Perl,现在,上面的脚本能够比较大约9GB到10GB的文件。但我想与超过50GB的超大文件进行比较。在运行我的脚本时,它已自动终止。有人能帮我提高性能,把这么大的文件和我的脚本进行比较吗 这是我的密码 use strict; use warnings; use Getopt::Std; use FileHandle; open STDOUT, ">", "output.txt" or die "$0: open: $!"; my %opts; my $optstr = "i:o:"; getop

现在,上面的脚本能够比较大约9GB到10GB的文件。但我想与超过50GB的超大文件进行比较。在运行我的脚本时,它已自动终止。有人能帮我提高性能,把这么大的文件和我的脚本进行比较吗

这是我的密码

use strict;
use warnings;
use Getopt::Std;
use FileHandle;

open STDOUT, ">", "output.txt" or die "$0: open: $!";
my %opts;
my $optstr = "i:o:";
getopts("$optstr", \%opts);
if($opts{i} eq '' || $opts{o} eq '' )
{
        print "usage: perl TextCompare_Fund.pl <-i INPUTFILE> <-o MAPREDUCE OUTPUTFILE>\n";
        die 1;
}
my $inputFilesPath=$opts{i};
my $outputFilesPath=$opts{o};
my @ifiles=`ls $inputFilesPath`;
my @ofiles=`ls $outputFilesPath`;
foreach my $ifile (@ifiles)
{
    my $ifile_substr=substr("$ifile",0,-25);
    foreach my $ofile (@ofiles)
    {
        my $ofile_substr=substr("$ofile",0,-25);
        my $result=$ifile_substr cmp $ofile_substr;
        if($result eq 0)
        {
            #print "$result\n";
            #print "$ifile\n";
            compare($ifile,$ofile)
        }
    }
}
sub compare
{
    my $afile="$_[0]";
    my $bfile="$_[1]";
    my $path1="$inputFilesPath/$afile";
    my $path2="$outputFilesPath/$bfile";
    chomp $path1;
    chomp $path2;
    #open FILE, "<", $path1 or die "$!:$path1";
    open my $infile, "<", $path1 or die "Couldn't open $path1: $!";
    my %a_lines;
    my %b_lines;
    my $count1=0;
    while (my $line = <$infile>) 
    {
        chomp $line;
            $a_lines{$line} = undef;
        $count1=$count1+1;
    }
    print"$bfile records count : $count1\n";
    close $infile;
    my $file=substr("$afile",0,-25);
    my $OUTPUT = "/hadoop/user/m6034690/Kishore/CompareResult_Files/$file.comparision_result";
    open my $outfile, "<", $path2 or die "Couldn't open $path2: $!";
    open (OUTPUT, ">$OUTPUT") or die "Cannot open $OUTPUT \n";

    my $count=0;
    my $count2=0;
    while (my $line = <$outfile>) 
    {
        chomp $line;
        $b_lines{$line} = undef;
        $count2=$count2+1;
        next if exists $a_lines{$line};
        $count=$count+1;
        print OUTPUT "$line \t===> The Line which is selected from file2/arg2 is mismatching/not available in file1\n";
    }   
    print "$bfile records count : $count2\n";
    print "Total mismatching/unavailable records in file1 : $count\n";
    close $outfile;
    close OUTPUT;
}
close (STDOUT);

您正在将整个文件加载到内存中。显然,这是不可能的

那么,您是否试图识别文件2中不在文件1中的行?如果对文件进行排序,则无需内存即可完成此操作。因此,首先对文件进行排序。unix排序实用程序可以处理任意大小的文件,所以让我们使用它

diff -u <( sort -u file1 ) <( sort -u file2 ) | tail -n +3 | grep ^+ | cut -c 2-


我看到您正在处理Hadoop环境的输出,并且担心文件太大而无法在一台机器上用Perl处理。幸运的是,Hadoop为您提供了一个使用多台机器的环境,无论您的问题是否存在。他们叫它

因此,如果您制作了一个映射器,将所有输入行映射到一个文件名,那么您可以在多个文件或文件拆分上运行多个这样的映射器,生成如下结果:

# key \t value
lineA \t file1
lineB \t file1
lineC \t file1
lineA \t file2
lineC \t file2
…
然后可以运行一组减速器来减少结果。映射程序对键进行散列,以确定键值对将发送到哪个减缩器,因此任何数量的将值附加在一起的减缩器都应生成正确的中间表示,如:

# key \t value-reduced
lineA \t file1 , file2
lineB \t file1
lineC \t file1 , file2
如果行本身使用该值存储,则可以将其存储到hdfs目录中的多个文件中。这可以通过配置单元映射到一个表,在该表中,您可以使用SQL语法查询感兴趣的行。或者,您可以在所有这些输入上运行另一个映射程序,以便在两个文件中删除您不感兴趣的行?在所有文件中,您可以处理更多文件

所有这些都可以使用a.ka实现。纯文本接口和perl/python/bash。尽管诚实地完美地实现它并不是我现在有时间做的事情。 输入文件名在中可用

有一种方法可以将输入按大小拆分到映射器。默认输入格式TextInputFormat支持未压缩文本的默认输入格式。但是,我找不到关于属性的正确文档,您可能会选择将拆分保留为256mb或其他什么


正如您所想象的,由于输入行几乎包含任何utf-8?值,您可能还需要更改默认的键值分隔符;这在先前链接的文档中。许多人使用标题0x01的开头或垂直选项卡0x0B。

输入文件的格式是什么?您的计算机有多少内存?因此您试图识别文件2中不在文件1中的行?@nmkishore如另一个问题中所述,我们只需要逐个读取行,而不是将所有内容存储在内存中,我现在要写一个答案。所以…这是一个关于在Hadoop运行的环境中处理大文件的Perl问题。你能用Hadoop吗?
# key \t value-reduced
lineA \t file1 , file2
lineB \t file1
lineC \t file1 , file2