2013-08-29 1 views
0

방법 좌표를 알고에 의해 문자열을 추출하는

내가 문자열을 포함 할말을 테잎에 파일에서 여러 문자열을 추출 할 ... 나는 몇 가지 질문에 내 문제에 당신을 귀찮게 정말 미안 해요,하지만 난 그것을 해결하기 위해 필요 내가 추출하려는 각 부분 문자열의 시작과 끝이있는 다른 파일을 사용하여. 첫 번째 파일은 같은 :

>scaffold30  24194 
CTTAGCAGCAGCAGCAGCAGTGACTGAAGGAACTGAGAAAAAGAGCGAGCTGAAAGGAAGCATAGCCATTTGGGAGTGCCAGAGAGTTGGGAGG GAGGGAGGGCAGAGATGGAAGAAGAAAGGCAGAAATACAGGGAGATTGAGGATCACCAGGGAG......... 
................. 

(문자열 첫 줄을 제외한 파일의 모든이어야 함), 및 좌표 파일과 같은 것입니다 :

:

44801988 44802104 
44846151 44846312 
45620133 45620274 
45640443 45640543 
45688249 45688358 
45729531 45729658 
45843362 45843490 
46066894 46066996 
46176337 46176464 
..................... 

내 스크립트가 이것이다

my $chrom = $ARGV[0]; 
my $coords_file = $ARGV[1]; 

#finds subsequences: fasta files 



open INFILE1, $chrom or die "Could not open $chrom: $!"; 
my $count = 0; 

while(<INFILE1>) { 
    if ($_ !~ m/^>/) { 

    local $/ = undef; 
    my $var = <INFILE1>; 

    open INFILE, $coords_file or die "Could not open $coords_file: $!"; 
      my @cline = <INFILE>; 
    foreach my $cline (@cline) { 
    print "$cline\n"; 
      [email protected] = split('\t', $cline); 
      my $start = $data[0]; 
      my $end = $data[1]; 
      my $offset = $end - $start; 
      $count++; 
      my $sub = substr ($var, $start, $offset); 
      print ">conserved $count\n"; 
      print "$sub\n"; 

    } 
    close INFILE; 
    } 
} 

실행할 때 첫 번째 파일의 시작 부분이 한 번만 반복되는 것처럼 보입니다. foreach 루프가 작동하지 않는 것 같습니다. 또한 substr이 작동하지 않는 것처럼 보입니다. 루프를 점검하기 위해 cline을 인쇄하기 위해 exit를두면, 좌표와 함께 파일의 모든 행을 인쇄합니다. 내가 성가신 될 경우

내가 미안 해요,하지만 난 그것을 완료해야하고 나는

는 다시 한번 감사드립니다 ... 조금 필사적입니다.

+0

해시 사용에 대해 생각해 보셨습니까? – fugu

+0

'$ chrom' 파일에 시퀀스가 ​​1 개만 있다고 가정합니다 - 맞습니까? ID가 '> scaffold30 24194 '입니다. –

+0

죄송합니다. 게시물을 다시 읽은 후 - * (문자열은 첫 번째 줄을 제외한 모든 파일이어야합니다) * –

답변

1

당신의 코드가 litt을 정리 될 수 제안 르. 원하는 솔루션 일 가능성이 있습니다.

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

my $chrom = $ARGV[0]; 
my $coords_file = $ARGV[1]; 

#finds subsequences: fasta files 

open INFILE1, $chrom or die "Could not open $chrom: $!"; 
my $fasta; 

<INFILE1>; # get rid of the first line - '>scaffold30  24194' 

while(<INFILE1>) { 
    chomp; 
    $fasta .= $_; 
} 
close INFILE1 or die "Could not close '$chrom'. $!"; 

open INFILE, $coords_file or die "Could not open $coords_file: $!"; 
my $count = 0; 

while(<INFILE>) { 
    my ($start, $end) = split; 

    # Or, should this be: my $offset = $end - ($start - 1); 
    # That would include the start fasta 
    my $offset = $end - $start; 

    $count++; 
    my $sub = substr ($fasta, $start, $offset); 
    print ">conserved $count\n"; 
    print "$sub\n"; 
} 
close INFILE or die "Could not close '$coords_file'. $!"; 
2

local $/ = undef; 

당신이 두 번째 파일에 읽기 섹션을 포함하는 전체 바깥 쪽 블록에 대한 $/ 변경이 줄. $/은 기본적으로 "줄"이 무엇인지 정의하는 입력 레코드 구분 기호입니다 (기본적으로 줄 바꿈입니다, 자세한 내용은 perldoc perlvar 참조). <>을 사용하여 파일 핸들러를 읽을 때, 어디에서 읽을 것인지를 결정하기 위해 $/이 사용됩니다. 예를 들어, 다음 프로그램은 기본 라인 분할 동작에 의존, 그래서 첫 번째 줄 바꿈까지 읽

local $/; 
my $foo = <DATA>; 
say $foo; 
# Output: 
# 1 
# 2 
# 3 

__DATA__ 
1 
2 
3 

이 수단 :

my $foo = <DATA>; 
say $foo; 
# Output: 
# 1 

__DATA__ 
1 
2 
3 

이 프로그램 반면 EOF에 모든 방법을 읽고 @cline 배열은 하나의 요소 만 가져옵니다.이 요소는 전체 좌표 파일의 텍스트를 포함하는 문자열입니다.

use Data::Dumper; 

print Dumper(\@cline); 

는 경우를 출력 뭔가처럼 어느 : 배열 (이 경우 기술적으로 arrayref가), []로 구분 방법

$VAR1 = [ 
      '44801988 44802104 
44846151 44846312 
45620133 45620274 
45640443 45640543 
45688249 45688358 
45729531 45729658 
45843362 45843490 
46066894 46066996 
46176337 46176464 
' 
     ]; 

공지 사항이 포함이이 Data::Dumper를 사용하여 볼 수 있습니다 개행을 포함하는 문자열 (작은 따옴표로 구분) 인 단일 요소 만. 코드의 관련 섹션을 통해

하자의 거리 : 보조 노트로

while(<INFILE1>) { 
    if ($_ !~ m/^>/) { 
     # Enable localized slurp mode. Stays in effect until we leave the 'if' 
     local $/ = undef; 

     # Read the rest of INFILE1 into $var (from current line to EOF) 
     my $var = <INFILE1>; 

     open INFILE, $coords_file or die "Could not open $coords_file: $!"; 

     # In list context, return each block until the $/ character as a 
     # separate list element. Since $/ is still undef, this will read 
     # everything until EOF into our first list element, resulting in 
     # a one-element array 
     my @cline = <INFILE>; 

     # Since @cline only has one element, the loop only has one iteration 
     foreach my $cline (@cline) { 

, 당신의 코드는 조금 정리 될 수있다.당신이 당신의 파일 핸들에 대해 선택한 이름은 아쉬움을두고 당신은 아마 어휘 어쨌든 파일 핸들 (및 open의 3 인자 양식)를 사용한다 : 또한

open my $chromosome_fh, "<", $ARGV[0] or die $!; 
open my $coordinates_fh, "<", $ARGV[1] or die $!; 

을, 당신은 당신의 루프에 둥지를 할 필요가 없습니다 이 경우 코드가 복잡해집니다.

# Get rid of the `local $/` statement, we don't need it 
my $chromosome; 
while (<$chromosome_fh>) { 
    next if /^>/; 
    $chromosome .= $_; 
} 

그런 다음 좌표 파일에 읽기 : 첫 번째 변수 (var보다 더 의미있는 이름 일)로 염색체 파일의 관련 부분을 읽어

my @cline = <$coordinates_fh>; 

을 또는 당신은 단지를 사용해야하는 경우 좌표의 내용은 while 루프 사용 가서 각 라인, 한 번 과정을 파일 : 'ThisSuitIsBlackNot'로

while (<$coordinates_fh>) { 
    # Do something for each line here 
} 
+0

문제는 $ var에있는 모든 파일을로드하려고하기 때문에이 줄을 사용한다는 것입니다. substring을 추출하기위한 좌표로 substr을 사용하기 위해서 – Vasilis

+0

@Vasilis 괜찮 았지만, 개행을 나누고 싶다면 두번째 파일을 읽기 전에'$ /'를'\ n'으로 바꾸어야합니다. – ThisSuitIsBlackNot

+0

나는 미안하지만 나는 그것을 얻지 못한다 ... – Vasilis

관련 문제