根据 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
.
来更慢地处理事情
我有 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
.