<p>You can do this simply enough in <code>awk</code>:</p>

<pre><code><span class="math-container">$ awk -F'_' '{
               split(FILENAME,n,/\./); 
               if(/^&gt;/){
                  sample=$1; 
                  sub(/&gt;/,"",sample); 
                  $</span>0="&gt;"n[1]
               }
               print &gt; sample".fasta"
             }' gene1.fasta gene2.fasta ... geneN.fasta
</code></pre>

<p>If I run this on the two files you gave, I get:</p>

<pre><code>$ cat sample1.fasta 
&gt;gene1
GATCTCGTAGATGTGA
&gt;gene2
ATGCTGTGAAGTA

$ cat sample2.fasta 
&gt;gene1
GATCTCGTAGATGTGA
&gt;gene2
ATGCTGTGAAGTA
</code></pre>

<h3>Explanation</h3>

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

CC BY-SA 4.0
2019-08-15T13:43:08.157Z
2019-08-15T13:49:14.023Z
2019-08-15T13:49:14.023Z
terdon
<p>I have eight fasta files, one per gene, with 106 fasta entries per file, like this:</p>

<p>gene1.fasta:</p>

<pre><code>&gt;sample1_434564
GATCTCGTAGATGTGA
&gt;sample2_2346764
GATCTCGTAGATGTGA
</code></pre>

<p>gene2.fasta:</p>

<pre><code>&gt;sample1_532345
ATGCTGTGAAGTA
&gt;sample2_6040103
ATGCTGTGAAGTA
</code></pre>

<p>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 <code>_</code> in the fasta headers, but the rest is unique for each fasta file. </p>

<p>Is  there any way to do this with <code>awk</code> or other command-line tools? </p>

<p>Desired output:</p>

<p>Sample1.fasta</p>

<pre><code>&gt;gene1
GATCTCGTAGATGTGA
&gt;gene2
ATGCTGTGAAGTA
</code></pre>

<p>Sample2.fasta</p>

<pre><code>&gt;gene1
GATCTCGTAGATGTGA
&gt;gene2
ATGCTGTGAAGTA
</code></pre>

CC BY-SA 4.0
2019-08-15T13:34:57.293Z
What operating system are you using? Do you have access to GNU tools? Is this a Linux machine or something else?
terdon
CC BY-SA 4.0
2019-08-15T13:35:36.183Z
@terdon It's on linux yes
Haakonkas
<fasta><text-processing>
Concatenate multiple fasta files into one file per unique entry
# Concatenate multiple fasta files into one file per unique entry

(Asked by: username_0 on 2019-08-15)

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

**Tags:** fasta, text-processing
> **Comments:**
> **username_1**: What operating system are you using? Do you have access to GNU tools? Is this a Linux machine or something else?  
> **username_0**: @terdon It's on linux yes  

---

## 1 answers

### Answer by username_1 on 2019-08-15. Score: 6 | Accepted answer

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.


---

