2012-02-29 8 views
0

この質問は非常に一般的ですが、少し条件が異なります。私は10のファイルがあり、私は共通の行を抽出したい。 特定の値と列に基づいて複数のファイルに共通の行が見つかります

comm [-1] [-2] [-3 ] file1 file2 

>

しかし、ファイルが3列(またはそれ以上の列)を持っている場合、私は最初の2列(またはそれ以上)のみを比較したいといない - >

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' file1 file2 file3 file4 

またはLinuxで - 私が見つかりました。最後に、カラム・>

ファイル1 - >

 
Col1 col2 col3 

A  1  0 
A  2  1

FILE2

 
Col1 col2 col3 

A  2 0.5 
A  1 10 
B  1 10 

所望の出力 - 出力中のSO>

 
Col1 col2 file1 file2 

A  1  0  10 
A  2  1  0.5

私は10個のファイルを持っている場合は、10の以上の列があるはずです。 1つのライナーperl(それを変更すること)でも可能ですか?それとも何ができますか?

+0

これを1行に入力する理由は何ですか?より明示的なコードで変更する方がより明確になりやすくなります。 – markw

答えて

1
use strict; 
use warnings; 
use Array::Utils qw(intersect); 

my $first_file=shift(@ARGV); 
my @common_lines=(); 

#Grab all of the lines in the first file. 

open(my $read,"<",$first_file) or die $!; 

while(<$read>) 
{ 
    chomp; 
    my @arr=split /\t/; 
    @[email protected][0,1]; #Only take first two columns. 
    push @common_lines,join("\t",@arr); 
} 

close($read); 
foreach my $file (@ARGV) 
{ 
    my @matched_lines=(); 
    open($read,"<",$file) or die $!; 
    while(<$read>) 
    { 
     chomp; 
     my @arr=split /\t/; 
     @[email protected][0,1]; 
     my $to_check=join("\t",@arr); 

     #If $to_check is in @common_lines, put it in @matched_lines 
     if(grep{$_ eq $to_check}@common_lines) 
     { 
      push @matched_lines,$to_check; 
     } 
    } 
    close($read); 

    #Take out elements of @common_lines that aren't in @matched_lines 
    @common_lines=intersect(@common_lines,@matched_lines); 

    unless(@common_lines) 
    { 
     print "No lines are common amongst the files!\n"; 
    } 
} 

foreach(@common_lines) 
{ 
    print "$_\n"; 
} 
関連する問題