2
$\begingroup$

I have a file contain multiple sequence, and I want to separate them by "gene:" into different file. example:

  • example.fa

    >KQK21959
    ATGGTGCTCGACCCCGTCGTCGGGGGCTCGGCCTCCCGCAAGGTCGAGCCCCTAACCCTA
    
    >KQK14546
    ATGCCTCCGCCGGACGCGGCCACCTACGCTCCCACGCTGCCAATGGCGACGTACCTCCCA
    
    • how to get results like this? one sequence per file, and after ">" is gene id, not cds id

KQK21959.fa

    >KQK21959
    ATGGTGCTCGACCCCGTCGTCGGGGGCTCGGCCTCCCGCAAGGTCGAGCCCCTAACCCTA

KQK14546.fa

    >KQK14546
    ATGCCTCCGCCGGACGCGGCCACCTACGCTCCCACGCTGCCAATGGCGACGTACCTCCCA
$\endgroup$
3
$\begingroup$

There's an app for that! The exonerate package (see here) includes a nice fastaexplode command that does exactly what you're looking for and will be much, much faster than anything we give you here since it is written in C and not a scripting language. Just install exonerate (you can do that with sudo apt install exonerate on Debian-based systems) and then:

fastaexplode file.fa

This will create these two files (file.fa is the original input file from your question):

$ ls
file.fa  KQK14546.fa  KQK21959.fa
$\endgroup$
2
$\begingroup$

A simple Biopython solution:

from Bio import SeqIO

for record in SeqIO.parse("example.fa", "fasta"):
    SeqIO.write(record, record.id + ".fa", "fasta")

Note, if you have multiple sequences with the same id, only the last sequence will be kept in the final output files

$\endgroup$
1
  • $\begingroup$ Thank you! It works excellent. $\endgroup$
    – lzh
    May 15 '20 at 3:06
2
$\begingroup$

This can also be done using awk. This is harder to read, but probably faster than python:

awk 'sub(/^>/,""){
        FILE=$0".fa"; 
    print ">"$0 >FILE; 
        next
    }{print > FILE}' file.fa. 

This will define a new output file FILE at each header line, whose filename is the header minus the > character, suffixed with .fa. And all lines in the file are appended to the current output file.

EDIT: Changed to a faster version found on: https://crashcourse.housegordon.org/split-fasta-files.html#using-awk-instead-of-csplitsed

$\endgroup$
0
2
$\begingroup$

That really depends on the tools you are using. If anything will do you can use the following python snippet.

If you know that each sequence is on a single line and your file isnt gigantic use this

EDIT

Updated so the file isn't read to memory at once to address @terdon point. Although, the above solutions are probably much better.

with open( "seqs.fasta" ) as f:
    out = ""
    
    for line in f:
        if not line.strip(): continue 
        if line.startswith( ">" ):
            if not type( out ) == str: out.close()
            gene = line[1:].strip().split()[0]
            out = open( f"{gene}.fa", "w" )
            out.write( line )
            continue 
        out.write( line.strip() )
    
```
$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.