
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가 아닌 문자의 나머지 시퀀스를 #
.