我想创建一个 bash 脚本,它接收一个 dna 文件并检查它是否没有换行符或空格字符,然后输出唯一的密码子及其出现的次数。我使用了以下代码,但密码子一直给我输出“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
shell。
该行应该读作
#!/bin/bash
(注意#
开头的 )。
然后,您awk
以一种永远行不通的方式将语法与 shell 代码混合在一起。
相反,保持简单并将文件分成三个字符组,对它们进行排序并计算您获得了多少个独特的字符:
$ fold -w 3 dnafile | sort | uniq -c
3 aac
2 acg
1 ttt
只要输入始终包含三个字符的倍数,并且没有嵌入空格或其他字符,这种方法就可以工作。
答案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:好的
aacacgaactttaacacg
文件2:空格
aacacgaact ttaacacg
文件3:换行符
aacacgaact
ttaacacg
file4:不是 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 ")