ATGCATGC
2つの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
使用bash
とtr
:
#!/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;
'