# Concatenate multiple fasta files into one file per unique entry

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

• What operating system are you using? Do you have access to GNU tools? Is this a Linux machine or something else? Aug 15 '19 at 13:34
• @terdon It's on linux yes Aug 15 '19 at 13:35

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.