2016-06-27 3 views
0

디렉토리에서 하나의 파일을 열고 다음 코드를 실행할 수 있습니다. 그러나 디렉토리 내의 여러 파일에 동일한 코드를 사용하려고하면 파일이 존재하지 않는다는 오류가 발생합니다.디렉토리에 여러 개의 파일을 열 때 "No such file"이 표시되지만 하나의 파일 만 열면 오류가 없습니다.

파일 이름을 올바르게 지정했는지, 올바른 형식인지, 현재 작업 디렉토리에 있는지, 올바르게 참조되어 있는지 확인하려고했습니다.

많은 사람들이 이전에이 오류가 있었음을 알고 비슷한 질문을 게시했지만 어떤 도움도 받으실 수 있습니다.

근무 코드 : 여기

#!/usr/bin/perl 

use warnings; 
use strict; 
use diagnostics; 

use List::Util qw(min max); 

my $RawSequence = loadSequence("LDTest.fasta"); 
my $windowSize = 38; 
my $stepSize = 1; 
my %hash; 
my $s1; 
my $s2; 
my $dist; 

for (my $windowStart = 0; $windowStart <= 140; $windowStart += $stepSize) { 

    my $s1 = substr($$RawSequence, $windowStart, $windowSize); 
    my $s2 = 'CGGAGCTTTACGAGCCGTAGCCCAAACAGTTAATGTAG'; 
      # the 28 nt forward primer after the barcode plus the first 10 nt of the mtDNA dequence 

    my $dist = levdist($s1, $s2); 

    $hash{$dist} = $s1; 

    #print "Distance between '$s1' and '$s2' is $dist\n"; 

    sub levdist { 
     my ($seq1, $seq2) = (@_)[ 0, 1 ]; 

     my $l1 = length($s1); 
     my $l2 = length($s2); 
     my @s1 = split '', $seq1; 
     my @s2 = split '', $seq2; 
     my $distances; 

     for (my $i = 0; $i <= $l1; $i++) { 
      $distances->[$i]->[0] = $i; 
     } 

     for (my $j = 0; $j <= $l2; $j++) { 
      $distances->[0]->[$j] = $j; 
     } 

     for (my $i = 1; $i <= $l1; $i++) { 

      for (my $j = 1; $j <= $l2; $j++) { 
       my $cost; 

       if ($s1[ $i - 1 ] eq $s2[ $j - 1 ]) { 
        $cost = 0; 
       } 
       else { 
        $cost = 1; 
       } 

       $distances->[$i]->[$j] = minimum(
        $distances->[ $i - 1 ]->[ $j - 1 ] + $cost, 
        $distances->[$i]->[ $j - 1 ] + 1, 
        $distances->[ $i - 1 ]->[$j] + 1, 
       ); 
      } 
     } 

     my $min_distance = $distances->[$l1]->[$l2]; 

     for (my $i = 0; $i <= $l1; $i++) { 
      $min_distance = minimum($min_distance, $distances->[$i]->[$l2]); 
     } 

     for (my $j = 0; $j <= $l2; $j++) { 
      $min_distance = minimum($min_distance, $distances->[$l1]->[$j]); 
     } 

     return $min_distance; 
    } 
} 

sub minimum { 
    my $min = shift @_; 

    foreach (@_) { 
     if ($_ < $min) { 
      $min = $_; 
     } 
    } 

    return $min; 
} 

sub loadSequence { 
    my ($sequenceFile) = @_; 
    my $sequence = ""; 

    unless (open(FASTA, "<", $sequenceFile)) { 
     die $!; 
    } 

    while (<FASTA>) { 
     my $line = $_; 
     chomp($line); 

     if ($line !~ /^>/) { 
      $sequence .= $line; #if the line doesn't start with > it is the sequence 
     } 
    } 

    return \$sequence; 
} 

my @keys = sort { $a <=> $b } keys %hash; 
my $BestMatch = $hash{ keys [0] }; 

if ($keys[0] < 8) { 
    $$RawSequence =~ s/\Q$BestMatch\E/CGGAGCTTTACGAGCCGTAGCCCAAACAGTTAATGTAG/g; 
    print ">|Forward|Distance_of_Best_Match: $keys[0] |Sequence_of_Best_Match: $BestMatch", "\n", 
      "$$RawSequence", "\n"; 
} 

내 비 작동 코드의 축약 버전입니다. 내가 포함되지 않았다 변경하지 않은 것들 :

헤더 및 전역 :

my $dir   = ("/Users/roblogan/Documents/FakeFastaFiles"); 
my @ArrayofFiles = glob "$dir/*.fasta"; 

foreach my $file (@ArrayofFiles) { 

    open(my $Opened, $file) or die "can't open file: $!"; 

    while (my $OpenedFile = <$Opened>) { 

     my $RawSequence = loadSequence($OpenedFile); 

     for (...) { 

      ...; 

      print 
        ">|Forward|Distance_of_Best_Match: $keys[0] |Sequence_of_Best_Match: $BestMatch", 
        "\n", "$$RawSequence", "\n"; 
     } 
    } 
} 

정확한 오류는 다음과 같습니다

Uncaught exception from user code: 
     No such file or directory at ./levenshtein_for_directory.pl line 93, <$Opened> line 1. 
    main::loadSequence('{\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf470\x{a}') called at ./levenshtein_for_directory.pl line 22 

93 :

 89 sub loadSequence{ 
    90   my ($sequenceFile) = @_; 
    91   my $sequence = ""; 
    92   unless (open(FASTA, "<", $sequenceFile)){ 
    93     die $!; 
    94   } 

라인 22 :

 18   foreach my $file (@ArrayofFiles) { 
    19    open (my $Opened, $file) or die "can't open file: $!"; 
    20    while (my $OpenedFile = <$Opened>) { 
    21 
    22     my $RawSequence = loadSequence($OpenedFile); 
    23 
+0

루프가 상당히 혼란스러워 보입니다.'@ ArrayofFiles'의 각 파일 이름에 대해 파일을 열고 각 줄을 읽습니다. 그런 다음, 각 행 (끝에있는 줄 바꿈 문자가있는 경우)을'loadSequence'에 건네면, 그 문자열을 파일 이름으로 처리하고 열려고합니다. 그게 정말로 당신이하고 싶은 일입니까? – tfb

+2

그것은 질문과 관련이 없지만'loadSequence'를'return \ $ sequence' 대신'return $ sequence'로 변경해야합니다. 현재의 형태는 아무런 이점이 없습니다. 즉, 모든 사람에게 혼란스러운'$$ RawSequence'를 코드에 붙여 넣어야한다는 것을 의미합니다 (이전 질문에서 발견 한 것처럼) (http://stackoverflow.com/questions/38044668)/0120-998-002) – Borodin

+0

단지 F3TA 파일이 몇 줄 이상인 경우 CPS의 Levenshtein 부분에 XS 모듈 중 하나를 사용하면 훨씬 쉽게 파일을 만들 수 있습니다. . 필자는 [Text :: Levenshtein :: Flexible] (https://metacpan.org/pod/Text::Levenshtein::Flexible)의 일부분이지만 XS 파일은 순수한 Perl보다 더 빠른 속도입니다. – mbethke

답변

2

나는 방금 "파스타 파일"이 정착 된 용어라는 것을 알았습니다. 그것을 인식하지 못했고 이전에 그들은 일부 파일이이고 파일 이름 등을 포함한다고 생각했습니다. @zdim이 이미 말했듯이,이 파일을 두 번 열었습니다.

다음 코드는 FASTA 파일 목록 (파일 이름 만)을 가져오고 각각의 파일 이름을 사용하여 loadSequence을 호출합니다. 이 서브 루틴은 주어진 파일을 열고 none-^> 행을 하나의 큰 행에 연결하고이를 리턴합니다.

# input: the NAME of a FASTA file 
# return: all sequences in that file as one very long string 
sub loadSequence 
{ 
    my ($fasta_filename) = @_; 
    my $sequence = ""; 
    open(my $fasta_fh, '<', $fasta_filename) or die "Cannot open $fasta_filename: $!\n"; 
    while (my $line = <$fasta_fh>) { 
     chomp($line); 
     if ($line !~ /^>/) { 
      $sequence .= $line; #if the line doesn't start with > it is the sequence 
     } 
    } 
    close($fasta_fh); 
    return $sequence; 
} 

# ... 

my $dir = '/Users/roblogan/Documents/FakeFastaFiles'; 
my @ArrayofFiles = glob "$dir/*.fasta"; 
foreach my $filename (@ArrayofFiles) { 
    my $RawSequence = loadSequence($filename); 
    # ... 
} 
1

파일을 두 번 열려고하는 것 같습니다. 라인

my @ArrayofFiles = glob "$dir/*.fasta"; 

당신에게 파일 목록을 제공합니다. 그런 다음

다음을 차례로 수행하십시오. 파일을 차례로 반복하고, 각각을 열고, 한 줄을 읽은 다음 loadSequence()에 전송합니다. 이미 열려있는 파일에서 선이고 -

그러나, 그 함수에서 다시

sub loadSequence{ 
    my ($sequenceFile) = @_; 
    my $sequence = ""; 
    unless (open(FASTA, "<", $sequenceFile)){ 
    # ... 

기능의 $sequenceFile 변수 $OpenedFile로 함수에 전달되는 파일을 열려고 파일 이름이 아니라 읽을 수 있습니다. 코드의 세부 사항에 대해서는 확실하지 않지만 표시되는 오류는이 코드와 일치하는 것으로 보입니다.

그것은 당신이 참으로 readdir를 수행하면 파일에 액세스해야 할 것 opendir와 함께, 당신에게 파일의 목록을 제공하는의 glob를 혼동되어있을 수 있습니다. $OpenedFile (예 : $line)의 이름을 바꾸어보세요.