Perl输出的列数太多

use*_*899 2 lookup perl match

我有一个相关标记结果表和一个疾病标记表.两个文件都有标题.

这是相关标记表的样子:

  snps_BCG24 gene_BCG24 statistic_BCG24 pvalue_BCG24    FDR_BCG24 beta_BCG24                 pair SharedOrUnique_BCG24 PercentileRank_BCG24 chr       cM   hg19pos    Diseasegene
rs11203184  C21orf128       -9.425704 4.008530e-12 2.501741e-05 -0.9199033 rs11203184_C21orf128      SharedSignalMO7         1.484874e-06  21  63.4452  43526430 notDiseasegene
rs11203184      C2CD2        2.290434 2.684575e-02 8.559484e-01  0.3114964     rs11203184_C2CD2    UniqueSignalBCG24         2.906046e-01  21  63.4452  43526430 notDiseasegene
Run Code Online (Sandbox Code Playgroud)

这就是疾病标记表的样子:

Chr  hg19Pos  hg18Pos       rsID           SNPname               hg19UCSC               hg18UCSC startLoc   endLoc
1  1247494  1237357    rs12103  var_chr1_1247494   chr1:1247494-1247494   chr1:1237357-1237357  1147494  1347494
1  2502780  2492640  rs6667605  var_chr1_2502780   chr1:2502780-2502780   
Run Code Online (Sandbox Code Playgroud)

如果相关标记和疾病标记位于同一染色体上(分别是相关的第9列= =疾病列0),那么我想检查我的相关标记的位置(相关表中的第11列)是否属于开始和疾病标志物的最终位置(疾病表中的第7列和第8列).

如果我的相关标记在该距离内,我想标记该关联标记"inLocus",否则,留空.结果输出将是具有两个制表符分隔列的文件:1)每个关联标记的名称与关联标记表2)的顺序相同inLocus或相关标记表中每个标记的空白状态.

我为此编写了一个perl脚本,但它不输出两列(一列用于关联的标记名称,另一列用于轨迹状态),而是输出一列,其中包含标记名称和不同数量的列"inLocus"- 而且并非总是相同列数.我不知道哪个标记确实存在"inLocus",因为每个输出列有时会有不同的状态.我需要在代码中更改什么才能使列表中的每个标记都获得明确的inLocus标签?将空白更改为打印"notLocus"会有所不同吗?这是我的代码:

#!/usr/bin/perl
use strict;
use warnings;

my $data_file1="/Users/Me/AssociatedMarkers.txt";
my $data_file2="/Users/Me/DiseaseMarkers.txt";
open(Main, $data_file1) || die("Could not open file!");

my $Line = 0;
my $Line1 = 0;
my @main = 0;
my @loci = 0;

#Generate output files
open(Result, ">AssociatedMarkersInLocus.txt");
 print Result "SNP\tinLocus?\n";
foreach $Line (<Main>) {
    #remove new line character
    open(DiseaseMarkers, $data_file2) || die("Could not open file!");
    $Line =~ s/[\n\r]//g;
    @main = split(/\t/,$Line);
    print Result "@main[0]";
    foreach $Line1 (< DiseaseMarkers >) {
        $Line1 =~ s/[\n\r]//g;
        @loci = split(/\t/,$Line1);
        if ((@main[9] eq @loci[0])&&(@main[11]>=@loci[7])&&(@main[11]<@loci[8])){
            print Result "\tinlocus";
            close(DiseaseMarkers);
        }
    }
print Result "\n";
}
close(Result);  
#Report completion
print "Program AssociatedMarkers finished. \n";
Run Code Online (Sandbox Code Playgroud)

以下是我得到的结果:

SNP inLocus?                
MarkerNameHeader 
MarkerName1 inLocus     inLocus     inLocus
MarkerName2
MarkerName3             inLocus
MarkerName4 inLocus     inLocus     inLocus
MarkerName5 inLocus
Run Code Online (Sandbox Code Playgroud)

这是我实际需要的结果格式:

MarkerName1 inLocus
MarkerName2
MarkerName3
MarkerName4 inLocus
Run Code Online (Sandbox Code Playgroud)

或者,如果有人知道如何直接将inLocus信息附加到我现有的AssociatedMarkers文件,那就更好了!

Dav*_*K-J 5

使用您的样本数据进行测试似乎很好..

一点点代码审查:

  1. 根据需要声明变量.全局可能会让人感到困惑.
  2. 使用词法范围的变量作为文件句柄
  3. 使用三个参数打开
  4. 试图关闭循环内的文件句柄可能不是你想要做的.我把它移出了几个范围
  5. last LINE 会让你摆脱DiseaseMarkers文件
  6. @foo[0] 应该 $foo[0]

很高兴看到你没有使用chop/ chomp!我修复了你的行结束正则表达式,使其更加便携..

无论如何,这应该解决它:

#!/usr/bin/perl
use strict;
use warnings;

my $data_file1 = "/Users/Me/AssociatedMarkers.txt";
my $data_file2 = "/Users/Me/DiseaseMarkers.txt";

#Open data file and create file handle
open(my $mainfh, '<', $data_file1) or die "Could not open file! $!";

#define variables and constants
#Generate output files
open(my $resultfh, '>', "AssociatedMarkersInLocus.txt") or die "Could not open file for write! $!";
print $resultfh "SNP\tinLocus?\n";

foreach my $Line (<$mainfh>) {
    #remove new line character
    open(my $dmfh, '<', $data_file2) or die("Could not open file! $!");
    $Line =~ s/[\f\n\r]*$//g;
    my @main = split(/\t/, $Line);
    print $resultfh "$main[0]";

    my $has_locus = 0;

    LINE: foreach my $Line1 (<$dmfh>) {
        $Line1 =~ s/[\f\n\r]*$//g;
        my @loci = split(/\t/,$Line1);

        if (($main[9]  eq $loci[0])
            && ($main[11] >= $loci[7])
            && ($main[11]<$loci[8])) {

            $has_locus = 1;
            print $resultfh "\tinlocus";
            last LINE;
        }
    }

    if ($has_locus == 0) {
        print $resultfh "\tnolocus";
    }

    print $resultfh "\n";
    close($dmfh);
}

close($resultfh);
close($mainfh);

#Report completion
print "Program AssociatedMarkers finished.\n";
Run Code Online (Sandbox Code Playgroud)