繁体   English   中英

perl脚本查找两个文件中匹配的字段

[英]perl script to find fields matching in two files

我有两个文件,想从两个文件中找到匹配的字段1和2,并在字段1和2匹配时从第二个文件中打印第三个字段。 文件1如下所示:

#CHR BP                                                                                                          
#1 9690639                                                                                                      
#1 7338706                                                                                                      
#1 7338707                                                                                                      
#1 7338717

文件2如下所示:

#1 10036 rs11928874 CT C 315.21 VQSRTrancheINDEL99.99to100.00AC=3;AF=0.063;AN=48;BaseQRankSum=0.297;DP=1469;FS=16.265;InbreedingCoeff=-0.0941;MLEAC=3;MLEAF=0.063;MQ=14.67;MQ0=0;MQRankSum=1.339

我编写了以下perl脚本,该脚本输出的行太多,不符合匹配条件:

my @loci;
open IN, "highalt_results.txt";
while (<IN>) {
    my @L = split;
    next if m/CHR/;
    push @loci, [ $L[0], $L[1] ];
}
close IN;

my $F = shift @ARGV;
open IN, "$F";
while (<IN>) {
    my @L = split;
    next if m/#CHROM/;
    foreach (@loci) {
        if ( $L[0] = ${$_}[0] ) {
            if ( $L[1] = ${$_}[1] ) {
                print "${$_}[0] ${$_}[1] $L[2]\n";
                next;
            }
        }
    }
}

有人可以指出脚本出了什么问题吗?

我认为这是您的错误所在:

    if ( $L[0] = ${$_}[0] ) {
        if ( $L[1] = ${$_}[1] ) {

等于是一项任务-因此永远都是正确的。 您可能需要== 或者,对于基于字符串的比较,可以使用eq

更笼统地说-我认为您应该做些真正的事情来收紧代码。

  • strictwarnings真的很好。
  • 用词法文件句柄open 3个参数是好open ( my $input, "<", $filename ) or die $!; -这样可以避免@ARGV指定的文件名可能引起的@ARGV (考虑一个名为'>/etc/passwd'
  • 您确实应该检查open是否成功。
  • 而且我可能建议不要在foreach循环中使用隐式变量,因为${$_}[0]并不是特别好。 使用->取消引用可以使代码更好。

我可能会将其重写为:

use strict;
use warnings;

my @loci;
open( my $loci_in, "<", "highalt_results.txt" ) or die $!;
while (<$loci_in>) {
    my ( $start, $end ) = split;
    next if m/CHR/;
    push @loci, [ $start, $end ];
}
close $loci_in;

my $filename = shift @ARGV;
open( my $input, "<", $filename ) or die $!;
while (<$input>) {
    next if m/#CHROM/;
    my ( $start, $end, $data ) = split;
    foreach my $pair (@loci) {
        if (    $start == $pair->[0]
            and $end == $pair->[1] )
        {
            print "$start $end $data\n";

        }
    }
}
close($input);

至少如果((L [0] = $ {$ } [0]){{((L [1] = $ {$ } [1])} {

您应该使用==或-eq进行比较

请清除您的数据文件格式。 我看不到匹配的字段

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM