2
$\begingroup$

I have eight fasta files, one per gene, with 106 fasta entries per file, like this:

gene1.fasta:

>sample1_434564
GATCTCGTAGATGTGA
>sample2_2346764
GATCTCGTAGATGTGA

gene2.fasta:

>sample1_532345
ATGCTGTGAAGTA
>sample2_6040103
ATGCTGTGAAGTA

What I want to do is create one fasta file per sample so that I get all gene sequences for that sample in one file. As you can see, the sample ID is the same before the _ in the fasta headers, but the rest is unique for each fasta file.

Is there any way to do this with awk or other command-line tools?

Desired output:

Sample1.fasta

>gene1
GATCTCGTAGATGTGA
>gene2
ATGCTGTGAAGTA

Sample2.fasta

>gene1
GATCTCGTAGATGTGA
>gene2
ATGCTGTGAAGTA
$\endgroup$
2
  • $\begingroup$ What operating system are you using? Do you have access to GNU tools? Is this a Linux machine or something else? $\endgroup$
    – terdon
    Commented Aug 15, 2019 at 13:34
  • $\begingroup$ @terdon It's on linux yes $\endgroup$
    – Haakonkas
    Commented Aug 15, 2019 at 13:35

1 Answer 1

6
$\begingroup$

You can do this simply enough in awk:

$ awk -F'_' '{
               split(FILENAME,n,/\./); 
               if(/^>/){
                  sample=$1; 
                  sub(/>/,"",sample); 
                  $0=">"n[1]
               }
               print > sample".fasta"
             }' gene1.fasta gene2.fasta ... geneN.fasta

If I run this on the two files you gave, I get:

$ cat sample1.fasta 
>gene1
GATCTCGTAGATGTGA
>gene2
ATGCTGTGAAGTA

$ cat sample2.fasta 
>gene1
GATCTCGTAGATGTGA
>gene2
ATGCTGTGAAGTA

Explanation

  • -F'_' : set the field separator to _ as an easy hack that lets us use $1 for the sample name (sample_NNN, so sample will be $1 and NNN will be $2).
  • split(FILENAME,n,/\./); : FILENAME always holds the name of the file currently being processed. Here, we are splitting it on . to get the gene's name. This assumes all of your files are named $geneName.fasta. The split creates the array n whose 1st element, n[1] is the gene name.
  • if(/^>/){ : if this is a fasta header line.
  • sample=$1 : set the variable sample to the sample's name. See the first note about -F'_'.
  • sub(/>/,"",sample); : remove the > from the sample variable. We don't want that in the file name.
  • $0=">"n[1] : set the current line to be > and the gene name.
  • print > sample".fasta" : print each (modified) line into the appropriate file name.
$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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