我一直在努力寻找找到相同模式的方法,并在它们的末尾添加一个标记,显示它们在文件中出现的次数。 例如,如果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
答案 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