合并具有相似列的多个文件

时间:2015-07-10 08:05:12

标签: perl awk

我有30个文件,其中第1列在每个文件中都相似。我想基于第1列加入文件,以便输出文件包含每个输入文件的第2列。我知道如何加入两个文件,但很难处理多个文件。

join -1 1 -2 1 File1 File2

文件以制表符分隔,没有像这样的标题

File1中

5S_rRNA 1324
5_8S_rRNA   32
7SK 15
ACA59   0
ACA64   0
BC040587    0
CDKN2B-AS   0
CDKN2B-AS_2 0
CDKN2B-AS_3 0
CLRN1-AS1   0

文件2

5S_rRNA 571
5_8S_rRNA   11
7SK 5
ACA59   0
ACA64   0
BC040587    0
CDKN2B-AS   0
CDKN2B-AS_2 0
CDKN2B-AS_3 0
CLRN1-AS1   0

输出

5S_rRNA 1324 571
5_8S_rRNA   32 11
7SK 15 5
ACA59   0 0 
ACA64   0 0
BC040587    0 0
CDKN2B-AS   0 0
CDKN2B-AS_2 0 0
CDKN2B-AS_3 0 0
CLRN1-AS1   0 0

2 个答案:

答案 0 :(得分:1)

随着文件大小的增加,第一个内存就出现了问题。其次,如果内容的排序不重要,那么这将有效。

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

my %hash;
my ($key,$value);
my @files=<files/*>;
foreach(@files){
open my $fh, '<', $_ or die "unable to open file: $! \n";
  while(<$fh>){
        chomp;
       ($key,$value)=split;
       push(@{$hash{$key}},$value);
    }
  close($fh);
}
for(keys %hash){
 print "$_ @{$hash{$_}} \n";
}

答案 1 :(得分:0)

下面的代码将给出你想要的输出,但是当文件数量增加时会占用更多的内存(正如你所说的有30个文件)。通过使用<div>,它按照其键的字母顺序对哈希进行排序(将按照您提到的相同顺序给出输出)。

sort

输出:

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

my @files = qw| input.log input1.log |; #you can give here path of files, or use @ARGV if you wish to pass files from command line 
my %data;

foreach my $filename (@files)
{
    open my $fh, '<', $filename or die "Cannot open $filename for reading: $!";
    while (my $line = <$fh>)
    {
        chomp $line;
        my ($col1, $col2) = split /\s+/, $line;
        push @{ $data{$col1} }, $col2; #create an hash of array
    }
}
foreach my $col1 (sort keys %data)
{
    print join("\t", $col1, @{ $data{$col1} }), "\n";    
}