DNA 评分脚本文件

DNA 评分脚本文件

我想对 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

最后,是最后一个的变体,但只有 和sedbc同样,只打印分数):

sed 'y/ATCG/1234/;s/\(.\)/+\1/g;s/^+//' file | bc 

Sundeep 提出了

sed 'y/ATCG/1234/;s/./+&/2g' file | bc

这是我最后一件事的较短变体。

它首先使用命令将字母更改为相应的数字y,然后将每个字符(从第二个字符开始)替换为前面加上 的字符本身+,因此对于输入字符串,ACCA您将得到1+3+3+1输出。 bc然后用于计算该算术表达式。

他的解决方案仅在 GNU 中有效,sed因为标准sed不喜欢同时获取和 作为替换标志2g

答案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

相关内容