我有30个文件,其中第1列在每个文件中都相似。我想基于第1列加入文件,以便输出文件包含每个输入文件的第2列。我知道如何加入两个文件,但很难处理多个文件。
join -1 1 -2 1 File1 File2
文件以制表符分隔,没有像这样的标题
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
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
答案 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";
}