我一直在努力使用 awk 找出一种方法来找到相同的模式,并在它们的末尾添加一个标签,显示它们在文件中存在的次数。 例如,如果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);a[$0]++;打印 $0"_"a[$0]}'
(从这里窃取的代码:找到出现次数并将其添加到模式旁边)
但是我找不到保存文件中更改的方法(例如,像 -i 的 sed),并且我无法将其重定向到新文件,因为它只是打印/保存标题。
有什么想法吗?
谢谢 P
似乎问题在于您不理解在其他地方找到的代码:
awk '$1 ~ /^>/ {gsub(" ", "", $0); a[$0]++; print $0"_"a[$0]}'
从外观上看,它执行您想要的替换并打印以>
开头的行。
因此,缺少的部分是打印其余行而不进行任何修改。
你可以这样做:
awk '$1 ~ /^>/ { gsub(" ", "", $0); a[$0]++; $0 = $0"_"a[$0] } { print }'
也就是说,将print
更改为第一个块中的赋值,并添加一个无条件的第二个块,该块始终打印所有内容。
通过将增量与赋值相结合,并将{ print }
更改为通用速记(只是默认操作的1
条件,打印),可以进一步简化代码。
如注释中所述,可以通过传递正则表达式文本作为第一个参数来改进对gsub
的调用,而不是在使用前必须转换为正则表达式的字符串。也可以通过删除最后一个参数$0
(默认值)来缩短它。
awk '$1 ~ /^>/ { gsub(/ /, ""); $0 = $0 "_" ++a[$0] } 1'
要覆盖原始文件,只需重定向到临时文件,然后覆盖原始文件:
awk '...' input > tmp && mv tmp input
或者使用 GNU awk,如评论中所述:
awk -i inplace '...' input