DNA 서열의 점수를 매기고 싶습니다.
A = 1 T = 2 C = 3 G = 4
내 입력은
ATGGCGATTGA
AGCTTAGCCAG
AGCTTAGGGAA
내 출력은
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
편집한 내 입력은 .txt 파일입니다.
답변1
sed -e 's/A/./g' -e 's/T/../g' \
-e 's/C/.../g' -e 's/G/..../g' file |
awk '{ printf("seq_number %d has score = %d\n", NR, length) }'
산출:
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
이 sed
명령은 각 베이스를 점수를 나타내는 여러 포인트로 대체합니다. 이 awk
명령은 지금까지 읽은 줄 수를 인쇄하고 줄의 총 점수인 줄 길이를 계산합니다.
첫 번째 sed
표현은 s/A/./g
실제로 정확할 필요는 없습니다.
변형(재미로 약간 더 짧음):
sed -e 's/G/TT/g;s/C/TA/g;s/T/AA/g' file |
awk '{ printf("seq_number %d has score = %d\n", NR, length) }'
한 줄에 하나씩 분수만 제공하는 변형:
tr 'ATCG' '1234' <file | awk -F'\0' -vOFS="+" '$1=$1' | bc
먼저 각 문자를 해당 문자의 분수로 바꾼 다음 ,를 사용하여 awk
각 숫자 사이에 삽입합니다. +
그런 다음 각 행의 총점 계산을 처리합니다 bc
.
마지막으로, 마지막 것의 변형이지만 합계만 포함됩니다 sed
( bc
다시 분수만 인쇄됩니다).
sed 'y/ATCG/1234/;s/\(.\)/+\1/g;s/^+//' file | bc
썬딥이 제안한
sed 'y/ATCG/1234/;s/./+&/2g' file | bc
이것은 내 마지막 것의 짧은 변형입니다.
먼저 명령을 사용하여 문자를 해당 숫자로 변경한 y
다음 각 문자(두 번째 문자부터 시작)를 이전 문자 자체로 바꾸 +
므로 입력 문자열에 대해 출력을 ACCA
얻습니다 . 그런 다음 이 산술 표현식을 평가하는 데 사용됩니다.1+3+3+1
bc
sed
그의 솔루션은 표준이 sed
get 및 as replacement 플래그를 모두 좋아하지 않기 때문에 GNU에서만 작동합니다 2
.g
답변2
간단한 awk 스크립트로 다음을 수행할 수 있습니다.
점수.awk
BEGIN {
values["A"]=1
values["T"]=2
values["C"]=3
values["G"]=4
}
{
split($0, letters, "");
sum=0;
for (letter in letters)
sum += values[letters[letter]];
print "seq_number", NR, "has score =", sum;
}
예제 데이터를 실행하면 다음과 같은 결과를 얻습니다.
$ awk -f score.awk < input
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
답변3
이제 어쨌든 질문에 대한 답이 나왔으니, 여기에 몇 가지 perl/ruby
농담이 있습니다.
$ perl -MList::Util=sum0 -lne 'print "seq_number $. has score = ", sum0 split //, tr/ATCG/1234/r' ip.txt
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
$ ruby -ne 'puts "seq_number #{$.} has score = #{$_.tr("ATCG", "1234").chars.sum(&:to_i)}"' ip.txt
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27
아이디어는 동일하며 문자가 단위 숫자로 변환되는 한 작동합니다.
- 따라서 먼저 해당 사용으로
tr
변경하십시오 .ATCG
1234
- 그런 다음 문자열을 문자별로 나누고 숫자를 합산하십시오.
그리고 awk
반환 값을 사용하는 버전split
$ awk 'BEGIN{a["A"]=1; a["T"]=2; a["C"]=3; a["G"]=4}
{score = 0; for(k in a) score += (split($0, n, k)-1)*a[k];
print "seq_number " NR " has score = " score}' ip.txt
seq_number 1 has score = 28
seq_number 2 has score = 28
seq_number 3 has score = 27