"C" 문자의 인쇄 패턴

"C" 문자의 인쇄 패턴

file.tsv에 제공된 각 줄에서 Cys 잔여물의 패턴을 인쇄하고 싶습니다. file.tsv에는 시퀀스 ID와 시퀀스라는 두 개의 열이 있습니다. 두 번째 열 시퀀스에서 첫 번째 문자 "C"는 C로 인쇄되어야 하며, 다음 바로 나머지 부분이 C가 아닌 경우 코드는 C#을 인쇄해야 합니다. # n개의 다양한 아미노산 발생에 대해 한 번만 발생해야 합니다.

따라서 열에서 "C" 뒤에 다른 문자가 오면 "C" 뒤에 #을 인쇄하고 싶습니다. 따라서 시퀀스 열에 DCFRCGHCC 값이 있으면 세 번째 열 C#C#CC에 인쇄되어야 합니다.

입력 예:

c32_g1_i1_ 3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
c32_g1_i1_ 6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX

출력은 세 개의 열(sequenceID, Sequence, Cys 패턴)이어야 합니다.

c32_g1_i1_3,GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS,C#C#C#C#C
c32_g1_i1_6,AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX,C#C#CC#C 

답변1

첫 번째 단일 라이너/전체 스크립트는 질문에 설명된 파일 형식을 구문 분석하고 변환합니다. 두 번째 전체 스크립트는 FASTA 파일 형식을 구문 분석하고 변환합니다.


#1

골프를 치는 한 줄짜리:

perl -lane 'my $s;my @m=$F[1]=~/C.?/g;foreach(@m){$_ eq"CC"?$s.="C":$s.="C#"}push(@F,$s);print(join(",",@F))' infile

확장된 전체 스크립트:

#!/usr/bin/perl

use strict;
use warnings;

@ARGV == 1 || die("Usage: <command> <input_file>\n");

open(my $in, $ARGV[0]) || die("Could not open input file \"$ARGV[0]\": $!\n");

while(<$in>) {
    my $string;
    my @fields = split(" ");
    my @matches = $fields[1] =~ /C.?/g;
    foreach(@matches) {
        $_ eq "CC" ? $string .= "C" : $string .= "C#"
    }
    push(@fields, $string);
    print(join(",", @fields) . "\n")
}

close($in);

exit

설명:

  • 입력 파일은 한 줄씩 처리됩니다.
  • 각 줄은 공백 앞 부분과 공백 뒤 부분의 두 문자열로 분할됩니다.
  • 두 번째 문자열에서 선택적으로 다른 문자(선택적으로 문자열 끝에서 "C" 문자도 포착하기 위해)가 뒤따르는 "C" 문자로 구성된 각 하위 문자열이 평가되며, "C" 다음의 문자가 " C", "C"는 사용자 정의 임시 문자열 끝에 추가됩니다. 그렇지 않으면 사용자 정의 임시 문자열 끝에 "C#"이 추가됩니다.
  • 첫 번째, 두 번째 및 사용자 정의 임시 문자열은 쉼표로 구분되어 인쇄되고 그 뒤에 개행 문자가 옵니다.

샘플 출력:

% cat infile
c32_g1_i1_3 GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
c32_g1_i1_6 AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX
% perl -ne 'my $s;my @f=split(" ");my @m=$f[1]=~/C.?/g;foreach(@m){$_ eq"CC"?$s.="C":$s.="C#"}push(@f,$s);print(join(",",@f)."\n")' infile
c32_g1_i1_3,GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS,C#C#C#C#C#
c32_g1_i1_6,AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX,C#C#CC#C#

#2

확장된 정식 버전:

#!/usr/bin/perl

use strict;
use warnings;

@ARGV == 1 || die("Usage: <command> <input_file>\n");

open(my $in, $ARGV[0]) || die("Could not open input file \"$ARGV[0]\": $!\n");
open(my $tmp, "+>", "tmpfile") || die("Could not create temporary file \"tmpfile\": $!\n");

select($tmp);

while(<$in>) {
    if(/^>/) {
        s/$/ /
    }
    if(my $next = <$in>) {
        if($next !~ /^>/) {
            chomp
        }
        print;
        seek($in, -length($next), 1)
    }
    else {
        print
    }
}

close($in);

seek($tmp, 0, 0);

select(STDOUT);

while(<$tmp>) {
    my $string;
    my @fields = split(/ (?!.* )|\n/);
    my @matches = $fields[1] =~ /C.?/g;
    foreach(@matches) {
        $_ eq "CC" ? $string .= "C" : $string .= "C#"
    }
    push(@fields, $string);
    print(join(",", @fields) . "\n")
}

close($tmp);

unlink("tmpfile");

exit

설명:

  • 입력 파일은 한 줄씩 처리됩니다.
  • 현재 줄이 문자로 시작하면 >줄에 공백이 추가됩니다. 다음 줄이 존재하고 문자로 시작하지 않으면 >현재 줄에서 개행 문자가 제거됩니다. 현재 줄은 임시 파일에 인쇄됩니다.
  • 임시 파일은 한 줄씩 처리됩니다.
  • 각 줄은 두 개의 문자열, 즉 마지막 공백 앞 부분과 마지막 공백 뒤 부분으로 분할됩니다.
  • 두 번째 문자열에서 선택적으로 다른 문자(선택적으로 문자열 끝에서 "C" 문자도 포착하기 위해)가 뒤따르는 "C" 문자로 구성된 각 하위 문자열이 평가되며, "C" 다음의 문자가 " C", "C"는 사용자 정의 임시 문자열 끝에 추가됩니다. 그렇지 않으면 사용자 정의 임시 문자열 끝에 "C#"이 추가됩니다.
  • 첫 번째, 두 번째 및 사용자 정의 임시 문자열은 쉼표로 구분되어 인쇄되고 그 뒤에 개행 문자가 옵니다.
  • 임시 파일이 제거됩니다.

샘플 출력:

% cat infile 
>c32_g1_i1_
3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS
>c32_g1_i1_
6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX
6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX
% perl script.pl infile 
>c32_g1_i1_,3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS3GQKAKLKVPVFFLHRRGSICSSFYLMFSFEIKKK*TSKN*CFVCVRVRNRERAGVKCAHVYCPMFNGTQTH*IIISSLNS,C#C#C#C#C#C#C#C#C#C#
>c32_g1_i1_,6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX6AV*TADDDLVRLCSIEHGTIHMCTLYTCCTLTVTHTYTHKTLIFACLFFFNFKGEHQIERAANRTSSM*KKHRNF*LGLLAX,C#C#CC#C#C#C#CC#C#

답변2

awk귀하에게 적합한 버전은 다음과 같습니다.

awk '{OFS=","; $3=$2; sub(/[^C]+/,"",$3); gsub(/[^C]+/,"#",$3); print}' file

두 번째 필드를 복제한 다음, 복제본에서 C가 아닌 문자의 비어 있지 않은 초기 시퀀스를 제거한 다음, C가 아닌 문자의 나머지 시퀀스를 #.

관련 정보