2つのDNA配列の比較

2つのDNA配列の比較

ATGCATGC2つのDNA配列がありますTACGTTGC

A比較がソートされたら「+」を提供し、TそれG以外の場合はC「-」を印刷するプログラムを作成したいと思います。

良い

ATGCATGC
TACGTTGC
+++++---

誰でも私を助けることができますか?

上記は予想される結果を提供します。

私が試したことは次のとおりです。

#!/bin/bash


declare -a seq1=()
declare -a seq2=()


read -p 'Enter the ncleotide seq (charactor by charactor followe\d by space0) ' -a seq1

read -n1 seq1

read -p 'Enter the ncleotide seq (charactor by charactor followe\d by space0) ' -a seq2

read -n1 seq2

for a in ${seq1[*]} ; do
for b in ${seq2[*]} ; do
if [ $a == A ] || [ $b == T ] ; then
echo -n "+"
elif [ $a == A ] || [ $b == C ] ; then
echo -n " -"
elif [ $a == A ] || [ $b == G ] ; then
echo -n "-"
elif [ $a == T ] || [ $b == A ] ; then
echo -n "+"
elif [ $a == T ] || [ $b == C ] ; then
echo -n "-"
elif [ $a == T ] || [ $b == G ] ; then
echo -n "-"
elif [ $a == C ] || [ $b == G ] ; then
echo -n "+"
elif [ $a == C ] || [ $b == A ] ; then
echo -n "-"
elif [ $a == C ] || [ $b == T ] ; then
echo -n "-"
elif [ $a == G ] || [ $b == C ] ; then
echo -n "+"
elif [ $a == G ] || [ $b == A ] ; then
echo -n "-"
elif [ $a == G ] || [ $b == T ] ; then
echo -n "-"
else  
echo $a $b
fi
done
done

答え1

使用awk:

awk -v seq1='CATGCATGCTCAT' -v seq2='ATACGTTGCGTTA' '
function sign(s) { cmp=(cmp==""?"":cmp) s }
BEGIN{
    split(seq1, tmp1, ""); split(seq2, tmp2, "");
    for(i in tmp1) {
        if( tmp1[i] == tmp2[i] ){ sign("-"); continue }
        if( (tmp1[i] ~/[AT]/ && tmp2[i] ~/[AT]/) || 
            (tmp1[i] ~/[GC]/ && tmp2[i] ~/[GC]/) ) { sign("+"); continue }
        sign("-")
    }
    print seq1 ORS seq2 ORS cmp
}'

出力:

CATGCATGCTCAT
ATACGTTGCGTTA
-+++++-----++

コメントを含む同じコード:

awk -v seq1='CATGCATGCTCAT' -v seq2='ATACGTTGCGTTA' '
# set sequences one in seq1 another in seq2

function sign(s) { cmp=(cmp==""?"":cmp) s }
# function to join the the changes on +/- for each pair of chars

BEGIN{
    split(seq1, tmp1, ""); split(seq2, tmp2, "");
    # split each sequences characters into individual arrays

    for(i in tmp1) {
    # loop over keys on one of the arrays (assuming length of both seq will be same)

        if( tmp1[i] == tmp2[i] ){ sign("-"); continue }
        # if both chars were same AA, TT, CC, GG, ..., sign should be "-"

        if( (tmp1[i] ~/[AT]/ && tmp2[i] ~/[AT]/) || 
            (tmp1[i] ~/[GC]/ && tmp2[i] ~/[GC]/) ) { sign("+"); continue }
        # if one was "A" and another was "T" or vice-versa as well as
        # if one was "G" and another was "C" or vice-versa, sign should be "+"

        sign("-")
        # otherwise "-"

    }
    print seq1 ORS seq2 ORS cmp
    # print the last result, first printing the sequences then 
    # the comparison result in 'cmp'
}'

答え2

使用bashtr:

#!/bin/bash

printf '%s\n%s\n' "$1" "$2"
tr 37124568 '++[-*]' <<<$(( $(tr ATCG 1234 <<<"$1 + $2") ))

テスト:

$ bash script ACCTACCATAG AGTACCCGATC
ACCTACCATAG
AGTACCCGATC
-+-+----+++

このスクリプトは、コマンドラインで指定された順序の文字を数字に置き換えるため、それらを一緒に加算すると、合計の数字3と7はを意味し、+他のすべての数字はを意味します-

文字は次のように変更されます。

A --> 1
T --> 2
C --> 3
G --> 4

つまり、A+Tは 1+2、つまり 3 と同じです。同様にC、合計の場合、7は3 + 4から来ますG

外部tr呼び出しはすべての3と7をに変換し+、他のすべての可能な数値をに変換します-。合計は、単純に2つのシーケンスの文字を数値に変更する$(( ... ))内部呼び出しによって生成された2つの数値を加算する算術拡張によって計算されます。tr

入力検証は行われません。オーバーフローなどの算術エラーはチェックされません(いくつかの基本ペアよりも長いシーケンスの場合、文字などで慎重に分離しないとオーバーフローが発生する可能性があります)。

標準入力からシーケンスを読み取るには、次のようにします。

#!/bin/bash

read s1
read s2

printf '%s\n%s\n' "$s1" "$s2"
tr 37124568 '++[-*]' <<<$(( $(tr ATCG 1234 <<<"$s1 + $s2") ))

答え3

read seq1
read seq2
printf '%s\n' "$seq1" "$seq2" |
sed -Ee '
  N;H;p;z;x

  :zip
    #   1  2     3
    s/\n(.)(.*\n)(.)/\1\3\n\2/
    s/\n\n//; # zipping is complete when the two markers collide
  t zip

  :cmp
  s/^([-+]*)(AT|TA|CG|GC)/\1+/;t cmp
  s/[ATCG]{2}/-/;t cmp
'

出力:

ATGCATGCTATC
TACGTTGCATTG
+++++---++-+

今回は別の方法を使ってアッhユーティリティ、+を提供し、残りは-を提供する適切なキーがあらかじめ埋められている連想配列の助けを借りて、2つのシーケンスを文字ごとに圧縮します。

awk '
BEGIN {
  OFS = ORS

  split("AT TA CG GC", a)
  for (var in a) h[a[var]]

  seq1 = ARGV[1]; seq2 = ARGV[2]
  len = length(seq1)

  while ( ++pos <= len ) {
    s = substr(seq1, pos, 1) \
        substr(seq2, pos, 1) ;
    res = res ((s in h) ? "+" : "-")
  }

  print seq1, seq2, res
}
' "$seq1" "$seq2"

私たちは使用Python 3文字列に格納され圧縮されたシーケンス比較を実行します。

python3 -c 'import sys
s,t = sys.argv[1::]
dna = "ATCG"
d = {i+j: "+" for i,j in zip(dna[0::2],dna[1::2])}
print(*[d.get(x+y,d.get(y+x,"-")) for x,y in zip(s,t)],sep="")
' "$seq1" "$seq2"

真珠上記のPythonの例を適用すると、次のようになります。

printf '%s\n' "$seq1" "$seq2" |
perl -F// -pale '
  my @h = qw(A T C G);
  my %h = (@h, reverse @h);
  my $zip = join q(), map { $F[$a++], $_ } <> =~ /./g;
  $_ = $zip ​=~ s/(.)(.)/qw(- +)[$2 eq $h{$1}]/reg;
'

関連情報