如果行以“>”开头,则使用awk查找模式并在其末尾添加模式的出现次数

时间:2017-03-21 13:14:01

标签: awk header fasta

我一直在努力寻找找到相同模式的方法,并在它们的末尾添加一个标记,显示它们在文件中出现的次数。 例如,如果Spiroplasma_culicicola发生7次,那么在第一次发生的旁边,它应该写Spiroplasma_culicicola_1,第二次出现Spiroplasma_culicicola_2旁边第三次出现Spiroplasma_culicicola_3等等

但是我有一个看起来像这样的fasta文件:

>Spiroplasma_taiwanense
GKGVKYKNEKIIRKEGKAAGKMTTDVIADMLTRIRNANQRFHKEVVIPGSKVKLEIANIL
KKEGFIEDFKVADDFKKDITISLKYRGKTRVIKGLKRISKPGLRVYSHATEIPQVLNGLG
IAIVSTSHGIMTDKEARQQNAGGEVLAFVW
>Spiroplasma_diminutum
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
KSKILRGDVVKVIAGSHKGKIGPVVKLSKDKKRVYVEGIVAIK-HAKPSQTDQEGGIREI
PAGVDISNVSLVDPKVKDSATRVGYKIADGKKVRIAKKSGSEVK-MIQNESRLKVADNSG
>Spiroplasma_diminutum
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
...

所以我想添加“标签”,这个数字只显示在标题旁边!因此上面的文件应如下所示:

>Spiroplasma_taiwanense_1
GKGVKYKNEKIIRKEGKAAGKMTTDVIADMLTRIRNANQRFHKEVVIPGSKVKLEIANIL
KKEGFIEDFKVADDFKKDITISLKYRGKTRVIKGLKRISKPGLRVYSHATEIPQVLNGLG
IAIVSTSHGIMTDKEARQQNAGGEVLAFVW
>Spiroplasma_diminutum_1
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
KSKILRGDVVKVIAGSHKGKIGPVVKLSKDKKRVYVEGIVAIK-HAKPSQTDQEGGIREI
PAGVDISNVSLVDPKVKDSATRVGYKIADGKKVRIAKKSGSEVK-MIQNESRLKVADNSG
>Spiroplasma_diminutum_2
NRLEKQYKEKIVPELFKEKQYKSIMQVPKITKVVINMGIGDAVQDTKKLDDAVLELQQIT
GQKPLVTKAKKSLAVFKLREGMPIGAKVTLRGKRMYEFLDKLISVALPRVRDFRGVPKTS
FDKQGNYTMGIKEQIIFPEIDYDKVKKVRGMDITIVTTANQKDEAFSLLQKMGMPFVKMN
...

基于之前回答的问题,我认为我应该使用awk,如下所示: awk'$ 1~ / ^> / {gsub(“”,“”,$ 0);一个[$ 0] ++;打印$ 0“_”a [$ 0]}'

(代码从这里被盗:find the number of occurences and add it next to the pattern

但是我找不到保存文件中更改的方法(例如sed with -i)并且我无法将其重定向到新文件,因此它只是打印/保存标题。

有什么想法吗?

感谢 P

1 个答案:

答案 0 :(得分:2)

问题似乎是你不了解你在其他地方找到的代码:

awk '$1 ~ /^>/ {gsub(" ", "", $0); a[$0]++; print $0"_"a[$0]}'

根据事物的外观,它会执行您想要的替换并打印以>开头的行。

所以缺少的部分是打印其余的行而不做任何修改。

你可以这样做:

awk '$1 ~ /^>/ { gsub(" ", "", $0); a[$0]++; $0 = $0"_"a[$0] } { print }'

也就是说,将print更改为第一个块中的赋值,并添加一个无条件的第二个块,它始终打印所有内容。

通过将增量与赋值相结合并将{ print }更改为公共简写(只有1条件和默认操作print,可以进一步简化代码。

正如评论中所提到的,可以通过将正则表达式文字作为第一个参数传递来改进对gsub的调用,而不是在使用前必须转换为正则表达式的字符串。也可以通过删除默认的最终参数$0来缩短它。

awk '$1 ~ /^>/ { gsub(/ /, ""); $0 = $0 "_" ++a[$0] } 1'

要覆盖原始文件,只需重定向到临时文件,然后覆盖原始文件:

awk '...' input > tmp && mv tmp input

或者使用GNU awk,如评论中所述:

awk -i inplace '...' input