텍스트 처리-펄

텍스트 처리-펄

나는 생물학자입니다. 텍스트 파일 편집에 도움을 줄 수 있는 컴퓨터 전문가의 도움을 받고 싶습니다.

입력 파일의 모습은 다음과 같습니다.

##dsfsd2
##sdf-sdf sasg 5.6.3
gi34_ex Gen  CDS     161     317     .       +       .       Name=Xm ZAK;created by=User
gi56_ex Gen  CDS     2194    2280    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  CDS     2848    2951    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  CDS     4554    4619    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  CDS     4729    4756    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  extracted region        1       11677   .       +       .       Name=Extracted region from gi|371443185|gb|JH556675.1|;Extracted interval="1960862 -> 1972538"

세 번째 행부터 입력에는 탭으로 구분된 12개($1 ~ $12) 열이 있습니다. 파일의 마지막 줄에는 탭으로 구분된 16개($1 ~ $16) 열이 있습니다. ## 행은 무시되어야 합니다.

마지막 줄(간격="1960862)의 $14를 취하고 싶습니다. 숫자(1960862)만 $4 열(161,2194,2848..4729)에 추가합니다. 즉(161+1960862=1961023,2194+1960862=1963056..) ) 및 $5 열(317,2280,2951..4756), 즉 (317+1960862=1961179,2280+1960862=1963142)에는 마지막 줄을 무시합니다.

출력은 다음과 같아야 합니다.

##dsfsd2
##sdf-sdf sasg 5.6.3
gi34_ex Gen  CDS     1961023     1961179     .       +       .       Name=Xm ZAK;created by=User
gi56_ex Gen  CDS     1963056    1963142    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  CDS     1963710    1963813    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  CDS     1965416    1965481    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  CDS     1965591    1965618    .       +       .       Name=Xm ZAK;created by=User
gi37_ex Gen  extracted region        1       11677   .       +       .       Name=Extracted region from gi|371443185|gb|JH556675.1|;Extracted interval="1960862 -> 1972538"

답변1

다음은 작동하는 솔루션입니다. 설명은 댓글에서 확인하실 수 있습니다.

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

open my $IN, '<', '1.in' or die $!;

my $line;
$line = $_ while <$IN>;                 # Remember the last line.
my $last = $.;                          # Remember the number of the last line.

my $interval = (split /\t/, $line)[13]; # Extract the 14th column.
$interval =~ s/[^0-9]+//;               # Keep only the number.

seek $IN, 0, 0;                         # Rewind to the beginning of the input.
$. = 0;                                 # Restart the line counter.
my $start = 1;                          # Flag to skip first lines.
while (<$IN>) {
    my @columns = split /\t/;
    /^##/ or undef $start;              # Unset start if the header is over.
    if (not ($start or $. == $last)) {  # Not header or last line?
        $_ += $interval for @columns[3, 4];
    }
    print join "\t", @columns;
}

관련 정보