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) }'

1行に1つずつ分数のみを提供するバリアント:

tr 'ATCG' '1234' <file | awk -F'\0' -vOFS="+" '$1=$1' | bc

まず、各文字をその文字の小数に置き換えてから、を使用してawk各数字の間に挿入します。+次に、各行の総点計算を処理しますbc

最後に、最後のもののバリアントですが、合計のみが含まれますsedbc再び分数のみが印刷されます)。

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

サンディップが提案した

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

これは私の最後のものの短い変形です。

まず、コマンドを使用して文字をその数に変更し、y各文字(2番目の文字から始まる)を前の文字自体に置き換えて、入力文字列の+出力を ACCA取得します。その後、この算術式を評価するために使用されます。1+3+3+1bc

sed彼のソリューションは、標準がsedgetとas replacementフラグの両方を好まないため、GNUでのみ機能します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変更してください。ATCG1234
  • 次に、文字列を文字で分割し、数字を合計します。


そして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

関連情報