首页 > 解决方案 > Perl 合并列并添加来自不同文本文件的新列

问题描述

我是 Perl 的初学者,我想将不同文本文件的内容合并并添加新列。

我的第一个文件有两列。

chr1    14548  
chr1    15240272  
chr1    68723  
chr1    80040  
chr1    29627919  
chr1    63585628   
chr1    177110  
chr1    199016  
chr1    63600119 

第二个文件有一列

chr1    15240272  
chr1    29627919  
chr1    63585628  
chr1    63600119  
chr1    63608794  
chr1    63620650  
chr1    65986172  
chr1    81620996  
chr1    89015871  
chr1    96384184 

第三个文件有一列

chr1    3014448   
chr1    3068620  
chr1    3079928  
chr1    3082514  
chr1    3176980   
chr1    3198886  
chr1    3212349  
chr1    3249189  
chr1    3265742  
chr1    3273096

我希望我的输出有 4 列。

chr1    14548   chr1    3014448  
chr1    15240272   0    0  
chr1    68723   chr1    3068620  
chr1    80040   chr1    3079928  
chr1    29627919   0    0  
chr1    82626   chr1    3082514  
chr1    63585628   0    0  
chr1    177110  chr1    3176980  
chr1    199016  chr1    3198886  
chr1    212740  chr1    3212349

如果是第 2 个文件中的 column1,则在输出文件的第 2 列和第 3 列中添加 0 值。否则逐行合并 file1 和 3 中的列。(chr1 14548 = chr1 3014448; chr1 68723 = chr1 3068620,它们都取决于序列顺序,如果我对列进行排序,则无法识别chr1 14548 = what

我的 Perl 代码

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

open my $input1, '<', "file1.txt"
    or die $!;
open my $input2, '<', "file2.txt"
    or die $!;
open my $input3, '<', "file3.txt"
    or die $!;
open my $outfile, '>', "output.txt"
    or die $!;
while ( my $l1 = <$input1> ) {
  my $l2 = <$input2>;
  my $l3 = <$input3>;
  chomp $l1;
  chomp $l2;
  chomp $l3;

  my @columns1 = split( /\t/, $l1 );
  my @columns2 = split( /\t/, $l2 );
  my @columns3 = split( /\t/, $l3 );
  if ( $columns2[1] == $columns1[1] ) {
    print $outfile join( "\t", $columns1[0], $columns1[1], '0', '0' ), "\n";
  }
  else {
    print $outfile
        join( "\t", $columns1[0], $columns1[1], $columns3[0], $columns3[1] ),
        "\n";
  }
}
close;

我的 Perl 脚本不能很好地工作。无法在输出中添加 0 值。

如果有人可以提供帮助,将不胜感激。

标签: perlmerge

解决方案


我想我明白了……虽然我不知道这个应用程序。

主要变化是您需要根据需要读取文件 2 和 3 以排列所有内容。

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

open my $input1, '<', "file1.txt" or die $!;
open my $input2, '<', "file2.txt" or die $!;
open my $input3, '<', "file3.txt" or die $!;
open my $outfile, '>', "output.txt" or die $!;

my $line2 = <$input2>;
chomp($line2);
my @columns2 = split(/\t/, $line2);

while ( my $line1 = <$input1> ) {
    chomp($line1);
    my @columns1 = split(/\t/, $line1);

    if (@columns1[1] eq @columns2[1]) {
        # Line from input 1 matches line from input 2
        # Prep for next match and output zeros

        $line2 = <$input2>;
        chomp($line2);
        @columns2 = split(/\t/, $line2);

        print($outfile join("\t", @columns1, 0, 0), "\n");
    } else {
        # Input 1 does not match input 2
        # Read input 3 and print
        my $line3 = <$input3>;
        print($outfile  $line2, "\t", $line3);
    }
}
# Script ends, file handles are automatically closed

推荐阅读