Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.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 如何使用另一个文件中的值优化一个文件中的搜索?_Perl_Search_Hash - Fatal编程技术网

Perl 如何使用另一个文件中的值优化一个文件中的搜索?

Perl 如何使用另一个文件中的值优化一个文件中的搜索?,perl,search,hash,Perl,Search,Hash,我有两种文件,比如A文件和B文件。 文件A有如下行 scaffold10920 13740 14020 chr19.3.4051.27470346.27470626 280 100.00 283 2 0 0 0 0 0 0 + chr16.1.1.10933.11218 285 0 285 scaffold476 838469

我有两种文件,比如A文件和B文件。 文件A有如下行

scaffold10920   13740   14020   chr19.3.4051.27470346.27470626  280     100.00
283     2       0       0       0       0       0       0       +       chr16.1.1.10933.11218   285     0       285     scaffold476     838469  193881  194166  1       285,    0,   193881,
{chr19.3.4051.27470346.27470626} -->  scaffold10920
文件B有这样的行

scaffold10920   13740   14020   chr19.3.4051.27470346.27470626  280     100.00
283     2       0       0       0       0       0       0       +       chr16.1.1.10933.11218   285     0       285     scaffold476     838469  193881  194166  1       285,    0,   193881,
{chr19.3.4051.27470346.27470626} -->  scaffold10920
前面的示例是每个文件中的一行。这两个文件中的所有字段都以制表符分隔

我想通过只保留与文件A中的第一个和第四个字段具有相同值的行来过滤文件B(例如
scaffold10920
chr19.3.4051.27470346.27470626
)。为此,我为这样的文件创建了一个哈希表

scaffold10920   13740   14020   chr19.3.4051.27470346.27470626  280     100.00
283     2       0       0       0       0       0       0       +       chr16.1.1.10933.11218   285     0       285     scaffold476     838469  193881  194166  1       285,    0,   193881,
{chr19.3.4051.27470346.27470626} -->  scaffold10920
我正在文件B中搜索

这是我的剧本:

#!/app/languages/perl/5.14.2/bin/perl
use strict;
use warnings;

use Data::Dumper;

my $chromosome = $ARGV[0];
my @mykeys     = `cat rightChromosome/$chromosome.scaffolds.txt| sort -u`;

my %hces_hash;
foreach my $key_line (@mykeys) {

    #$key_line = $_;
    chomp($key_line);
    my @token = split('\t', $key_line);
    my $hce   = $token[3];
    my $scaff = $token[0];
    $hces_hash{$hce} = $scaff;
}

#print Dumper(\%hces_hash);

foreach my $key (keys %hces_hash) {

    chomp($key);

    my $scaffold = $hces_hash{$key};

    my $command  = "cat psl_best/$chromosome.best.psl|grep -w $key";
    my @belongs  = `$command`;
    chomp(@belongs);

    my $count = scalar(@belongs);

    foreach my $element (@belongs) {

        my @element_token = split('\t', $element);
        my $scaff_psl     = $element_token[13];
        my $hce_name      = $element_token[9];

        if ($scaffold eq $scaff_psl) {

            #print "$element\n";
            open FILE, ">>psl_raw/$chromosome.best.raw.psl" or die $!;
            print FILE "$element\n";
        }
    }

我的脚本正在运行,但速度非常慢。有什么方法可以优化它吗?

这会更快,因为它只读取每个文件一次。我无法测试它,因为我没有数据,但我检查了它是否编译。您可能想更改一些变量的名称,但我已经做了最好的猜测

它的工作原理是使用scaffolds文件的字段1和字段4中的键构建散列,键之间有一个选项卡。散列值是不相关的-只是一个正数。然后,它读取最佳文件并从字段14和10构建相同的密钥,并在将记录打印到输出文件之前简单地检查该密钥是否出现在散列中

您不应该使用Perl来做一些简单的事情,比如读取文件。只有当您需要做一些超出Perl能力范围的事情时,才有必要这样做。我在
sort
调用中根本看不到任何意义,因为它只是花时间对数据进行排序,一旦数据存储在散列中,这些数据将再次变得无序

#!/app/languages/perl/5.14.2/bin/perl
use strict;
use warnings;
use 5.010;
use autodie;

our @ARGV = qw/ chr2 /;

chdir 'psl_files';

my $raw_dir = 'psl_raw';

if ( -e $raw_dir ) {
  die qq{Can't make "$raw_dir"\n} unless -d $raw_dir;
  # ' fix highlighting
}
else {
  mkdir $raw_dir;
}

my ($chromosome) = @ARGV or die "Usage: $0 <chromosome>\n";

my $scaff_file = "rightChromosome/$chromosome.scaffolds.txt";
my $best_file  = "psl_best/$chromosome.best.psl";
my $raw_file   = "psl_raw/$chromosome.best.raw.psl";

# For provided data
$scaff_file = "chr2.scaffolds.txt";
$best_file  = "chr2.best_noHeaded.psl";

open my $scaff_fh, '<', $scaff_file;
my %hces_hash;
while ( <$scaff_fh> ) {
  chomp;
  my @fields = split /\t/;
  my $key = join "\t", @fields[0,3];
  ++$hces_hash{$key};
}
close $scaff_fh;

open my $best_fh, '<', $best_file;
open my $raw_fh,  '>', $raw_file;
while ( <$best_fh> ) {
  chomp;
  my @fields = split /\t/;
  my $key = join "\t", @fields[13,9];
  print $raw_fh "$_\n" if $hces_hash{$key};
}
close $raw_fh;
close $best_fh;
#/app/languages/perl/5.14.2/bin/perl
严格使用;
使用警告;
使用5.010;
使用自动模具;
我们的@ARGV=qw/chr2/;
chdir“psl_文件”;
my$raw_dir='psl_raw';
如果(-e$raw\U dir){
死亡qq{无法生成“$raw_dir”\n}除非-d$raw_dir;
#'修复突出显示
}
否则{
mkdir$raw_dir;
}
my($chromose)=@ARGV或die“用法:$0\n”;
my$scaff_file=“RightChromose/$chromose.scaffolds.txt”;
my$best\u file=“psl\u best/$chromose.best.psl”;
my$raw\u file=“psl\u raw/$chromose.best.raw.psl”;
#对于提供的数据
$scaff_file=“chr2.scaffolds.txt”;
$best_file=“chr2.best_noHeaded.psl”;

打开我的$scaff_fh,'这样文件B中的字段10和14必须匹配文件A中任何记录的字段4和1。
rightcomeron/$chromone.scaffolds.txt
是文件A,
psl_best/$chromone.best.psl
是文件B。对吗?没错。文件A(字段4作为键,字段1作为值)必须与文件B(字段10和14)匹配。
grep
(*nix实用程序,不要与Perl的内置工具混淆)将读取文件中的每一行。当您在循环中调用
grep
时,您正在多次读取文件的每一行。这是非常低效的。正如Borodin在下面指出的,当您可以用纯Perl做同样的事情时,不需要使用像
grep
这样的外部命令来读取文件。另外,
cat文件| grep foo
最好写成
grep foo文件
。将数据加载到SQLite表中。使用SQL。不,不幸的是没有。它生成了文件,但不正确。此外,它还会给我错误:“在连接或字符串中使用未初始化的值,位于./pslRaw_new_version_2.pl第28行,第1行。”然后,要么数据文件包含与所显示记录不同的记录,要么最有可能的是,字段未按制表符分隔。如果你找不到问题,那么把你的数据文件的样本,给我的链接,这样我就可以自己工作。你可以把
说成标量@字段在第27行之后,查看该行拆分为多少字段,我解决了警告消息。它现在没有抱怨,但我无法理解为什么输出不同。我可以把投递箱里的两个文件寄给你吗?我对pastebin不太熟悉。我可能不会很快给你回复。英国是晚上10:30是的,我知道。我也在英国。:)不用着急。我们把它留到明天吧。非常感谢你