根据 header 拆分 fasta 文件

Split fasta files based on header

我有 1,500 个 fasta 文件,里面有很多蛋白质片段。我的目标是将这些片段分成单个文件,并为这些文件命名一些直观的东西。

这里是我命名为 plate9 的 fasta 文件的例子。H7.faa:

>39_fragment_4_295  (310978..311196)    1   None    hypothetical protein
MQTATKQETYDRTMKVTLAVKANGGSVTVQIQAGDNWITTDTFWKDGGYQLSIPPATIRYVPAAGAAFEVYA*
>39_fragment_4_296  (311193..312437)    1   VOG01158    REFSEQ hypothetical protein
MSLLVNPIPRRQPIRRGLGLLGDSFSGNCHTIAATAFGTEAYGYAGWIAARTGLFPSYVDNQGKLGDHTGQFLARLPACIASSTADLWLLLSRTNDSTTAGMSLADTKANVMKIVTAFLNTPGKYLIIGTGTPRFGSRALTGQALADAIAYKDWVLSYVSQFVPVVNIWDGFTEAMTVEGLHPNLLGAEFISSRVVPIITANFEFPGIPLPTDAGDIYSAIRPFGCLNANPLLAGTGGTLPAGVNAAAGSVLADGYKAVGSGLTGITTRWFKEPAAYGEAQCIELRGNMAAAGGYIYMQPTANVVQTNLAAGDVIEMVSAVEIMGSSRGILAWEAELTITKTVSGAASTFYYRSMDKYQEPFTMPASFSGALETQRGTIDLTETVITSRMGLYLAAGVPQDSTVKAAQFGIRKV*
>56_fragment_9_667  (768674..769846)    -1  K14059  int; integrase
MGRDGRGVRAVSDTSIEITFMYRGVRCRERITLKPSPTNLKKAEQHKAAIEHAISIGAFDYSVTFPGSPRAAKFAPEANRETVAGFLTRWLDGKKRHVSSSTFVGYRKLVELRLVPALGERMVVDLKRKDVRDWLSTLEVSNKTLSNIQSCLRSALNDAAEEELIEVNPLAGWTYSRKEAPAKDDDVDPFSPEEQQAVLAALNGQARNMMQFALWTGLRTSELVALDWGDIDWLREEVMVSRAMTQAAKGQAEVPKTAAGRRSVKLLRPAMEALKAQKAHTFLADAEVFQNPRTLQRWAGDEPIRKTMWVPAIKKAGVNYRRPYQTRHTYASMMLSAGEHPMWVAKQMGHSDWTMIARVYGRWMPYWDDIAGTKAVSQWAENAHESSDSK*
>56_fragment_9_668  (770054..770281)    -1  PF02599.16  Global regulator protein family
MLCLSRRVGESIVIGDNIKITVISGRDGQIRLGIDAPAELAVDRSEVRTAKLATPCGIGLKLRTVAESGARDDEG*
>56_fragment_9_669  (770485..770697)    1   None    hypothetical protein
MECTTTADEVYGPRNAKLGKRAVDGNIWSGTTMIFRIIDDRVYSMHEQYLGRLKYGMAMTDRGELIFIVR*
>56_fragment_9_670  (770705..771487)    -1  VOG00563    sp|Q05292|VG77_BPML5 Gene 77 protein
MSESTIDPKKLERAIRKIKHCLALSQSSNENEAATAMRQAQALMREYHLTETDVKVSDVGEVESSMSRAARRPLWDQQLSAVVATVFNVKALRYTHWCETKKNRVERAKFVGVSPAQHIALYAYETLLAKLSQARNAYVAGVRAGKFRSSYSAPTAGDHFAIAWVFAVESKLQQLVPRGEENTTPEYKGAGPGLVAVEAQHQALIDSYLADKQVGKARKVRGSELDLNAQIAGMLAGTKVDLHAGLANGAEHAQVLPASA*

到目前为止,我已经能够使用此命令将文件拆分为多个文件:

for x in *.faa; do csplit -z $x '/>/' '{*}'; done

然后根据header中的片段重命名:

for file in xx*; do mv "$file" `head -1 "$file" | cut -d$'\t' -f 1`_$x.fasta; done

然后将每个文件重命名为没有每个文件中的“>”,并为其分配原始文件名:

for i in *.fasta; do mv $i `echo $i | cut -c 2-`; done

我的问题是这对单个文件有效(因为我正在执行的目录中有临时文件,临时文件称为 xx00、xx01、xx02、xx03 等等..

我觉得我的解决方案是遍历每个 fasta 文件并在开始下一个 fasta 文件之前连续执行所有这些 for 循环,我觉得那必须是一个嵌套的 for 循环,我有我自己从来没有做过。任何关于我可以做什么的指导都将不胜感激。

awk 可以打印到变量中定义的输出。
使用上面的示例数据:

$: ls -l *.fasta
-rw-r--r-- 1 P2759474 1049089 1124 Jun 21 08:56 tmp.fasta

$: for f in *.fasta; do 
     awk '/^>/ { sub(/^>/, "", ); f=; next; } 
          { print >> f; close(f); }' "$f"
   done

$: grep . 56_*
56_fragment_9_667:MGRDGRGVRAVSDTSIEITFMYRGVRCRERITLKPSPTNLKKAEQHKAAIEHAISIGAFDYSVTFPGSPRAAKFAPEANRETVAGFLTRWLDGKKRHVSSSTFVGYRKLVELRLVPALGERMVVDLKRKDVRDWLSTLEVSNKTLSNIQSCLRSALNDAAEEELIEVNPLAGWTYSRKEAPAKDDDVDPFSPEEQQAVLAALNGQARNMMQFALWTGLRTSELVALDWGDIDWLREEVMVSRAMTQAAKGQAEVPKTAAGRRSVKLLRPAMEALKAQKAHTFLADAEVFQNPRTLQRWAGDEPIRKTMWVPAIKKAGVNYRRPYQTRHTYASMMLSAGEHPMWVAKQMGHSDWTMIARVYGRWMPYWDDIAGTKAVSQWAENAHESSDSK*
56_fragment_9_668:MLCLSRRVGESIVIGDNIKITVISGRDGQIRLGIDAPAELAVDRSEVRTAKLATPCGIGLKLRTVAESGARDDEG*
56_fragment_9_669:MECTTTADEVYGPRNAKLGKRAVDGNIWSGTTMIFRIIDDRVYSMHEQYLGRLKYGMAMTDRGELIFIVR*
56_fragment_9_670:MSESTIDPKKLERAIRKIKHCLALSQSSNENEAATAMRQAQALMREYHLTETDVKVSDVGEVESSMSRAARRPLWDQQLSAVVATVFNVKALRYTHWCETKKNRVERAKFVGVSPAQHIALYAYETLLAKLSQARNAYVAGVRAGKFRSSYSAPTAGDHFAIAWVFAVESKLQQLVPRGEENTTPEYKGAGPGLVAVEAQHQALIDSYLADKQVGKARKVRGSELDLNAQIAGMLAGTKVDLHAGLANGAEHAQVLPASA*

有帮助吗?您还可以 运行 awk 在后台并行处理它们,或者使用 parallel.

您将通过使用不需要一直打开和关闭文件的工具来提高性能。 awk 是一个很好的选择。

在我看来,与您所写内容类似的结果可以通过以下方式实现:

$ awk '/^>/ { file=substr(,2) ".fasta" } { print > file }' *.faa

请注意,除非您 close() 一个文件,否则 awk 会在 awk 进程完成之前将其保持打开状态,因此如果它们出现在多个输入文件中,上述解决方案将附加到公共片段名称。

如果您有大量此类文件(数万),那么 *.faa 可能会扩展到太多文件,您的 shell 无法在一个命令行上处理。如果是这样,您可以使用 find.

来更慢地处理事情