2012-09-07 40 views
1

我有兩個文件讀取多個目錄中的文件,並與另一個文件

比較
File 1 in reading directory is of following format 

Read 1 A T 
Read 3 T C 
Read 5 G T 
Read 7 A G 
Read 10 A G 
Read 12 C G 

File 2 in directory contains 

    Read 5 A G 
    Read 6 T C 
    Read 7 G A 
    Read 8 G A 
    Read 20 A T 

文件2包含

1 
2 
3 
4 
5 
6 
7 

我需要閱讀的文件2首先爲positons並打印出從相應的值以水平方式在目錄中打開文件。如果該位置不匹配,則打印爲「 - 」。上面的輸出應該是

 1 2 3 4 5 6 7 
Read T - C - T - G 
Read - - - - G C A 

我需要爲所有文件做這件事,並在上面的格式打印在另一行。所以輸出將只有一個文件,其行數等於文件的數量。我可以在Perl中輕鬆做到這一點嗎?

+0

這應該像功課 - 請顯示你已經嘗試過,人們更可能幫助你 –

+0

這是通過手段沒有家庭工作。我是生物信息學的新手,並試圖在工作場所學習這門語言。我也不是在尋找整個解決方案。我只需要一個方向。我正在讀第二個文件,首先打開位置,然後打開目錄並逐個打開文件並將內容推送到數組。那麼在那之後,我不知道如何比較打開文件的位置。還有如何水平打印它們? – user630605

+1

您有三個輸入文件,其中兩個稱爲「File2」。輸入如何映射到期望的輸出並不明顯。例如,爲什麼第1列包含「 - T」(或者我甚至可以正確讀取它)? (第一個)File2是否總是覆蓋來自File1的輸入,就像它在輸出中的第5列中顯示的一樣?請編輯你的問題。 – tripleee

回答

0

如果文件大小是小,你可以閱讀到內存:

#read input files 
use IO::File; 
my $file1_data; 
open(my $file1_fh,"<","/path/file1.data") or die $!; 
#read file1 
while(my $line=<$file1_fh>){ 
    chomp($line); 
    my ($read,$pos,$col1,$col2) = split(/ /,$line); 
    $file1_data->{$pos} = [$col1,$col2]; 
} 
#read file2 
my $file2_data; 
open(my $file2_fh,"<","/path/file2.data") or die $!; 
while(my $line=<$file2_fh>){ 
    chomp($line); 
    my ($read,$pos,$col1,$col2) = split(/ /,$line); 
    $file2_data->{$pos} = [$col1,$col2]; 
} 
#read pos file 
my @positions; 
while(my $pos=<$posfile_fh>){ 
    chomp($pos); 
    push(@positions,$pos) 
} 
foreach my $pos (@positions){ 
    print "$pos\t"; 
} 
print "\n"; 
foreach my $pos (@positions){ 
    my $data = defined $file1_data->{$pos}->[0]?$file1_data->{$pos}->[0]:"-"; 
    print "$pos\t$data" 
} 
print "\n"; 
foreach my $pos (@positions){ 
    my $data = defined $file2_data->{$pos}->[0]?$file2_data->{$pos}->[0]:"-"; 
    print "$pos\t$data" 
} 
print "\n"; 
0

據我所看到的,你只使用第二個數據列。這裏有一個簡單的perl程序來做到這一點,如果有任何問題,隨時問。我使用了第三個輸入文件,可以根據需要使用盡可能多的文件。我改變了格式在最後包括42

代碼:

#!/usr/bin/env perl 

use strict; 
use warnings; 
use autodie; 

# try to open format file 
my $ffn = shift @ARGV or die "you didn't provide a format file name!\n"; 
open my $ffh, '<', $ffn; 

# read format file 
my @format = <$ffh>; 
close $ffh; 
chomp for @format; # get rid of newlines 

# prepare output 
print '  ' . join(' ' => @format) . "\n"; 

# iterate over all .txt files in the data directory 
foreach my $data_fn (<data/*.txt>) { 

    # iterate over all lines of the data file 
    open my $data_fh, '<', $data_fn; 
    my %data =(); 
    foreach my $line (<$data_fh>) { 

     # parse input lines (only) 
     next unless $line =~ /Read (\d+) ([ACGT]) ([ACGT])/; 
     my ($pos, $first, $second) = ($1, $2, $3); 

     # store data 
     $data{$pos} = $second; 
    } 

    # print summary 
    print 'Read ' . join(' ' => map {$data{$_} // '-'} @format) . "\n"; 
} 

輸出:

$ perl bio.pl format.txt 
    1 2 3 4 5 6 7 42 
Read T - C - T - G - 
Read - - - - G C A - 
Read - C - T - - - A 

HTH! :)

相關問題