【问题标题】:Split fasta files based on header根据标题拆分fasta文件
【发布时间】:2021-06-21 11:49:09
【问题描述】:

我有 1,500 个 fasta 文件,其中包含许多蛋白质片段。我的目标是将这些片段分成单个文件,并以直观的方式命名这些文件。

下面是我称之为 plate9.H7.faa 的 fasta 文件示例:

>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

然后根据它们在头部的片段重命名:

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 循环我。任何关于我能做什么的指导将不胜感激。

【问题讨论】:

    标签: linux bash for-loop nested-loops fasta


    【解决方案1】:

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

    在我看来,可以通过以下方式获得与您所写内容相似的结果:

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

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

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

    【讨论】:

    • 谢谢你,我总是忘记 awk 但这很好用。您知道如何将每个文件保存为原始文件名,然后保存为片段标题名称吗?现在您的命令仅将其保存为片段名称。
    • 我想通了:for i in *.faa;执行 awk '/^>/ { file=substr($1,2) ".fasta" } { print > file }' $i |重命名 fasta $i *.fasta;完成
    • 正如我在回答中所说,我建议不要在 for 循环中做事;如果您在文件本身中处理所有处理,您将获得更好的性能。我很难判断您的 rename 命令在做什么; Linux 中有几个同名的工具,具有不同的行为。如果您可以使用一些您正在寻找的输出示例(即文件名)来更新您的问题,我很乐意相应地更新我的答案。
    【解决方案2】:

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

    $: ls -l *.fasta
    -rw-r--r-- 1 P2759474 1049089 1124 Jun 21 08:56 tmp.fasta
    
    $: for f in *.fasta; do 
         awk '/^>/ { sub(/^>/, "", $1); f=$1; 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

    【讨论】:

    • 由于可能有数千个输出文件,您需要在打印到它后close(f)
    • 如果您还想在文件中保留标题行,请删除 next
    • 这几乎是我所需要的。我需要命令根据 > 之后和“片段”之前的第一个数字来分隔片段。我更新了这个问题,以更能反映我需要发生的事情。对不起,我之前不清楚
    • (所以我的示例文件分成两个新文件,因为有 39_fragment 和 56_fragment)
    • 我重新问了这个问题,因为我改变了我需要对我的代码做什么。昨天我认为将每个片段分成不同的文件会有所帮助,但实际上并不是我需要的。 .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多