DNA ファイルを取り込んで改行文字や空白文字がないことを確認し、固有のコドンとその発生回数を出力する bash スクリプトを作成したいと考えています。次のコードを使用しましたが、コドンから「bash-3.2$」が出力され続けます。構文が間違っているのか、なぜ適切な出力が得られないのか、非常に困惑しています。
! /bin/bash
for (( pos=1; pos < length - 1; ++pos )); do
codon = substr($1, $pos, 3)
tr-d '\n' $1 | awk -f '{print $codon}' | sort | uniq -c
done
たとえば、dnafileという名前のファイルにaacacgaactttaacacgというパターンが含まれている場合、スクリプトは次の入力と出力を受け取ります。
$script dnafile
aac 3
acg 2
ttt 1
答え1
スクリプトの最初の行で新しいbash
シェルが開始されるため、この出力が得られます。
その行は
#!/bin/bash
(#
先頭の に注意してください)。
そうすると、awk
決して機能しない方法で構文とシェル コードを混在させることになります。
代わりに、シンプルに、ファイルを 3 文字のグループに分割し、これらを並べ替えて、一意の文字がいくつあるかを数えます。
$ fold -w 3 dnafile | sort | uniq -c
3 aac
2 acg
1 ttt
これは、入力に常に 3 文字の倍数が含まれており、埋め込まれたスペースやその他の文字が含まれていない限り機能します。
答え2
(echo aacacgaactttaacacg ;echo aacacgaactttaacacg ) |
perl -ne '# Split input into triplets (A3)
# use each triplet as key in the hash table count
# and increase the value for the key
map { $count{$_}++ } unpack("(A3)*",$_);
# When we are at the end of the file
END{
# Remove the key "" (which is wrong)
delete $count{""};
# For each key: Print key, count
print map { "$_ $count{$_}\n" } keys %count
}'
答え3
少し長めのawk
バージョン
awk 'BEGINFILE{print FILENAME; delete codon}
ENDFILE {
if (NR!=1 || NF!=1 || length($0)%3!=0){
print "is broken"}
else{
for (i=1; i<=length($0); i+=3) codon[substr($0,i,3)]++};
for (c in codon) print c, codon[c];
print ""}' file*
この入力
ファイル1: OK
aacacgaactttaacacg
ファイル2: スペース
aacacgaact ttaacacg
ファイル3: 改行
aacacgaact
ttaacacg
ファイル4: 3 基数の倍数ではありません
aacacgaactttaacac
あなたは得る
file1
aac 3
ttt 1
acg 2
file2
is broken
file3
is broken
file4
is broken
ファイルを修復するだけで、例のように、ファイルを一方または他方から通過させるようなfile4
ものcat
がtr
ないawk
場合
<<< $(cat file[1..3] | tr -d "\n ")