<p>I recommend to use Biopython as a clearer way.</p>
<pre><code>from Bio import SeqIO

records = []
for record in SeqIO.parse(&quot;file.fas&quot;, &quot;fasta&quot;):
    record.description += &quot;;&quot;
    records.append(record)
SeqIO.write(records, &quot;file.fas&quot;, &quot;fasta&quot;)
</code></pre>
<p>Before:</p>
<pre><code>&gt;OK087550.1 Procyon lotor isolate Plo1 cytochrome b gene, partial cds; mitochondrial
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAGATCGCAACAG
GTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCATCAGTGACCCACATTTGCCG
AGATGTAAATTATGGCTGAATTATCCGATATATACACGCTAACGGAGCTTCTATATTCTTTATATGCCTA
TTCTTACACGTAGGACGAGGCTTATACTATGGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTA
TTTTACTACTCACAGTAATAGCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTG
AGGAGCAACAGTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATTCTACCATTTA
TTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGATCCAATAATCCTGCTGGAAT
TACATCAGAATCTGACAAAATTCCATTTCACCCATACTACACCATTAAAGACATTCTGGGAATCCTATTC
CTTATTTTTATACTTATAGGTTTAGTGCTATTTACGCCAGACCTACTAGGAGACCCAGATAACTACACAC
CCGCCAACCCCTTAAGCACCCCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCT
ACGTTCCATTCCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCATTCTGATTCC
TAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAATATCCCTTCATCATCATCGG
CCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTCCT

&gt;OK087549.1 Procyon lotor isolate Plo17 cytochrome b gene, partial cds; mitochondrial
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAGATCGCAACAG
GTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCATCAGTGACCCACATTTGCCG
AGATGTAAATTATGGCTGAATTATCCGATATATACACGCTAACGGAGCTTCTATATTCTTTATATGCCTA
TTCTTACACGTAGGACGAGGCTTATACTATGGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTA
TTTTACTACTCACAGTAATAGCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTG
AGGAGCAACAGTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATTCTACCATTTA
TTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGATCCAATAATCCTGCTGGAAT
TACATCAGAATCTGACAAAATTCCATTTCACCCATACTACACCATTAAAGACATTCTGGGAATCCTATTC
CTTATTTTTATACTTATAGGTTTAGTGCTATTTACGCCAGACCTACTAGGAGACCCAGATAACTACACAC
CCGCCAACCCCTTAAGCACCCCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCT
ACGTTCCATTCCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCATTCTGATTCC
TAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAATATCCCTTCATCATCATCGG
CCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTCCT

&gt;OK087548.1 Procyon lotor isolate Plo11 cytochrome b gene, partial cds; mitochondrial
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTTGGAATTTGTTTGCTTCTACAGATCGCAACAG
GTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCATCAGTGACCCACATTTGCCG
AGATGTAAATTATGGCTGAATTATCCGATATATACACGCTAACGGAGCTTCTATATTCTTTATATGCCTA
TTCTTACACGTAGGACGAGGCTTATACTATGGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTA
TTTTACTACTCACAGTAATAGCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTG
AGGAGCAACAGTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATTCTACCATTTA
</code></pre>
<p>After:</p>
<pre><code>&gt;OK087550.1 Procyon lotor isolate Plo1 cytochrome b gene, partial cds; mitochondrial;
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAG
ATCGCAACAGGTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCA
TCAGTGACCCACATTTGCCGAGATGTAAATTATGGCTGAATTATCCGATATATACACGCT
AACGGAGCTTCTATATTCTTTATATGCCTATTCTTACACGTAGGACGAGGCTTATACTAT
GGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTATTTTACTACTCACAGTAATA
GCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTGAGGAGCAACA
GTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATT
CTACCATTTATTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGA
TCCAATAATCCTGCTGGAATTACATCAGAATCTGACAAAATTCCATTTCACCCATACTAC
ACCATTAAAGACATTCTGGGAATCCTATTCCTTATTTTTATACTTATAGGTTTAGTGCTA
TTTACGCCAGACCTACTAGGAGACCCAGATAACTACACACCCGCCAACCCCTTAAGCACC
CCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCTACGTTCCATT
CCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCA
TTCTGATTCCTAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAA
TATCCCTTCATCATCATCGGCCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTC
CT
&gt;OK087549.1 Procyon lotor isolate Plo17 cytochrome b gene, partial cds; mitochondrial;
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAG
ATCGCAACAGGTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCA
TCAGTGACCCACATTTGCCGAGATGTAAATTATGGCTGAATTATCCGATATATACACGCT
AACGGAGCTTCTATATTCTTTATATGCCTATTCTTACACGTAGGACGAGGCTTATACTAT
GGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTATTTTACTACTCACAGTAATA
GCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTGAGGAGCAACA
GTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATT
CTACCATTTATTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGA
TCCAATAATCCTGCTGGAATTACATCAGAATCTGACAAAATTCCATTTCACCCATACTAC
ACCATTAAAGACATTCTGGGAATCCTATTCCTTATTTTTATACTTATAGGTTTAGTGCTA
TTTACGCCAGACCTACTAGGAGACCCAGATAACTACACACCCGCCAACCCCTTAAGCACC
CCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCTACGTTCCATT
CCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCA
TTCTGATTCCTAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAA
TATCCCTTCATCATCATCGGCCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTC
CT
&gt;OK087548.1 Procyon lotor isolate Plo11 cytochrome b gene, partial cds; mitochondrial;
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTTGGAATTTGTTTGCTTCTACAG
ATCGCAACAGGTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCA
TCAGTGACCCACATTTGCCGAGATGTAAATTATGGCTGAATTATCCGATATATACACGCT
AACGGAGCTTCTATATTCTTTATATGCCTATTCTTACACGTAGGACGAGGCTTATACTAT
GGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTATTTTACTACTCACAGTAATA
GCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTGAGGAGCAACA
</code></pre>

CC BY-SA 4.0
2022-04-06T08:35:29.437Z
Clearer than what? Why is using a complex package requiring several lines of code "clearer" than using standard *nix tools and one liners?
terdon
CC BY-SA 4.0
2022-04-06T09:29:09.543Z
@terdon For the same reasons fasta, nexus, &c. are explicit. It is easier to read at a glance.
Vovin
CC BY-SA 4.0
2022-04-06T09:52:13.050Z
I find this much harder to read than the standard tools with their simple syntax. I need to grok 6 lines of code here _and_ manually enter the file name twice with no autocompletion. You also don't mention that you need to install biopython, while the other solutions work out of the box on pretty much any *nix system. On the whole, this is longer, more complex, less portable and significantly slower than either the perl or sed one-liners. This took 6.7s compared to 2s for Perl and 1.6s for sed on a ~300MB file. It does work, but let's stick to the technical and remove the opinion :).
terdon
CC BY-SA 4.0
2022-04-06T09:59:58.697Z
@terdon Of course, you are right from this side. But it reminds me the times when I have only 105 bytes of programme memory & try use the address byte of GOTO as hex-command forwarding on it from another GOTO because it was more effective :-)
Vovin
CC BY-SA 4.0
2022-04-06T10:09:12.850Z
Heh, fair. But I just honestly don't find this in any way clearer. It certainly took me more seconds to understand this than any of the other answers. You are obviously more used to python than to perl or sed, so of course you will find it clearer. I am familiar with python, perl and sed, and of the three solutions, this was the least clear since it had more text to read. Everyone's experience is different! :)
terdon
CC BY-SA 4.0
2022-04-06T12:30:39.440Z
@terdon As someone who has taught programming to juniors I would bet a significant amount of money that a larger percentage of 'people in IT' will correctly "decode" what this does compared to any regex based solution. The strength of regexes is their flexibility, not their cleanness or readability. Appending a character at the end of a line really isn't playing to the strengths of regexes.
David Mulder
CC BY-SA 4.0
2022-04-06T12:42:49.360Z
@DavidMulder oh sure, _programmers_ are more likely to be familiar with python, no question about that. Old school bioinformaticians/*nix geeks like myself, less so. In any case, it was the unsubstantiated "clearer" that rubbed me the wrong way, since it is so very subjective and happens to be wrong in my own case.  And it also feels like using a tank to swat a fly: we're loading all sorts of fancy tools that just make this a slower, less efficient solution.
terdon
CC BY-SA 4.0
2022-04-06T14:13:51.793Z
@DavidMulder I'm with @terdon on this one - I don't find this solution clearer at all. It might appear easier to read at a glance, perhaps because `record.description += ";"` seems rather innocuous, but what happens if we're now presented with a FASTA file without a description field? Well, you need to know that in this case the description attribute is actually assigned the record id/name. So appending a semicolon to the description attribute will actually _create_ a description field in the output file, basically duplicating the record id/name. Probably not what anyone expected or wanted.
Steve
CC BY-SA 4.0
2022-04-06T14:41:44.533Z
**Steve's point deserves emphasis.** I love Biopython but its implementation of the `id` versus `description` attributes on SeqRecord objects never fails to trip me up.
Jesse
CC BY-SA 4.0
2022-04-06T23:21:30.680Z
This script loads all sequences into memory, which wouldn't work for huge input.
user172818
CC BY-SA 4.0
2022-04-05T17:38:56.023Z
2022-04-05T17:38:56.023Z
Vovin
<pre><code>seqkit replace -p &quot;$&quot; -r &quot;;&quot; my.fasta &gt; my.renamed.fasta
</code></pre>
<ul>
<li>Where <code>-p</code> is the pattern to match the end of the header text <code>$</code></li>
<li>Where <code>-r</code> is the replacement pattern</li>
</ul>
<p><a href="https://bioinf.shenwei.me/seqkit/usage/#replace" rel="nofollow noreferrer">https://bioinf.shenwei.me/seqkit/usage/#replace</a></p>
<p>Seqkit is an extremely powerful toolkit for working with fasta/fastq files. It can a lot with a single cli command.</p>

CC BY-SA 4.0
2023-07-10T16:39:27.927Z
2023-07-10T16:39:27.927Z
Ammar
<p>One way, using <a href="/questions/tagged/sed" class="post-tag" title="show questions tagged &#39;sed&#39;" rel="tag">sed</a> and a regex <a href="https://www.gnu.org/software/sed/manual/html_node/Addresses.html" rel="noreferrer">address</a> to select only the header lines and apply a substitution to append a semicolon to the end of each line:</p>
<pre><code>sed '/^&gt;/s/$/;/' in.fa &gt; out.fa
</code></pre>
<p>Or, to edit the file in place:</p>
<pre><code>sed -i '/^&gt;/s/$/;/' in.fa
</code></pre>
<hr />
<p>Or one way using <a href="/questions/tagged/awk" class="post-tag" title="show questions tagged &#39;awk&#39;" rel="tag">awk</a> and a ternary construct to print the line followed by a semicolon or an empty string, depending on whether or not the line is a header line:</p>
<pre><code>awk '{ print $0 (/^&gt;/ ? &quot;;&quot; : &quot;&quot;) }' in.fa &gt; out.fa
</code></pre>
<p>Alternatively, you may prefer:</p>
<pre><code>awk '/^&gt;/ { print $0 &quot;;&quot;; next } { print $0 }' in.fa &gt; out.fa
</code></pre>
<p>Which is the same as:</p>
<pre><code>awk '/^&gt;/ { print $0 &quot;;&quot;; next }1' in.fa &gt; out.fa
</code></pre>
<hr />
<p>If you have <a href="/questions/tagged/perl" class="post-tag" title="show questions tagged &#39;perl&#39;" rel="tag">perl</a> installed, all you need is:</p>
<pre><code>perl -pe 's/$/;/ if /^&gt;/' in.fa &gt; out.fa
</code></pre>

CC BY-SA 4.0
2022-04-06T02:39:53.477Z
2022-04-06T11:19:42.127Z
2022-04-06T11:19:42.127Z
Steve
<p>... using the legendary Perl pie</p>
<pre><code>perl -p -i -e 's/^(&gt;.*)/$1;/' mybacteria.fa
</code></pre>
<p><strong>Input</strong></p>
<pre><code>&gt;Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
&gt;Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG
A
</code></pre>
<p><strong>Output</strong></p>
<pre><code>&gt;Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106;
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
&gt;Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414;
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG
</code></pre>
<p><strong>Details</strong> I copy pasted your first code into a file <code>mybacteria.fa</code> then ran the Perl pie script. Perl pie is very quick, there alternative regexs (regular expressions) that would be slightly more efficient, but Perl pie is fast regardless. In fact you don't need to use regex in this example and would be faster via a <code>if $line == '&gt;';</code> declaration (certainly true for Pythonic equivalents <code>if line == '&gt;'</code>) but it doesn't offer the ease and flexibility, which is combined with speed, that Perl pie does. The code will work in Linux (any flavour/flavor) or Mac OSX Darwin (i.e. Terminal app)</p>

CC BY-SA 4.0
2023-07-09T20:30:15.850Z
@CallahanMcGovern if an answer worked for you, can you please mark it as accepted?
gringer
CC BY-SA 4.0
2022-04-06T02:50:45.657Z
It will work on any flavour/flavor so long as Perl is installed. Note that not all distributions ship with Perl pre-installed. Also, the capture group is not necessary - all that's needed here is: `perl -pe 's/$/;/ if /^>/' in.fa > out.fa`. Note that using `-i` without an extension will modify the input file in-place without making a backup of the original.
Steve
CC BY-SA 4.0
2022-04-06T11:34:50.837Z
In fairness I did point that out in the discussion below the code. The efficiencies are generally not noticeable. However, most regex manipulations take place within the string rather than at the end requested here, and capture can be one way to deal with different situations beyond this one.
M__
CC BY-SA 4.0
2022-04-06T12:15:07.307Z
Fair point. Perl is included in most popular Linux versions including Ubuntu, Debian and Suse. Perl isn't preinstalled on RedHat or freeBSD after release 5 and nobody uses Kali in bioinformatics. Let me know if there's anything missed.
M__
CC BY-SA 4.0
2022-04-07T00:46:57.137Z
Thank you very much -- this worked well and was simple to execute.
Callahan McGovern
CC BY-SA 4.0
2022-04-05T17:00:46.050Z
2022-04-06T08:40:21.867Z
2022-04-06T08:40:21.867Z
M__
<p>I have a large fasta file with RNA sequences. I need to add a <code>;</code> at the end of each header line (lines beginning with <code>&gt;</code>) in the file.</p>
<p>For example, I have:</p>
<pre><code>&gt;Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
&gt;Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG
</code></pre>
<p>And, my desired output is:</p>
<pre><code>&gt;Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106;
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
&gt;Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414;
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG
</code></pre>

<phylogenetics><fasta><phylogeny><bash><bacteria>
How can I add a ";" at the end of each fasta header line in a file?
# How can I add a ";" at the end of each fasta header line in a file?

(Asked by: username_0 on 2022-04-05)

I have a large fasta file with RNA sequences. I need to add a ; at the end of each header line (lines beginning with >) in the file.
For example, I have:
>Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
>Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG

And, my desired output is:
>Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106;
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
>Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414;
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG

**Tags:** phylogenetics, fasta, phylogeny, bash, bacteria

---

## 4 answers

### Answer by username_4 on 2022-04-06. Score: 7

One way, using sed and a regex address to select only the header lines and apply a substitution to append a semicolon to the end of each line:
sed '/^>/s/$/;/' in.fa > out.fa

Or, to edit the file in place:
sed -i '/^>/s/$/;/' in.fa


Or one way using awk and a ternary construct to print the line followed by a semicolon or an empty string, depending on whether or not the line is a header line:
awk '{ print $0 (/^>/ ? ";" : "") }' in.fa > out.fa

Alternatively, you may prefer:
awk '/^>/ { print $0 ";"; next } { print $0 }' in.fa > out.fa

Which is the same as:
awk '/^>/ { print $0 ";"; next }1' in.fa > out.fa


If you have perl installed, all you need is:
perl -pe 's/$/;/ if /^>/' in.fa > out.fa


---

### Answer by username_8 on 2022-04-05. Score: 6

... using the legendary Perl pie
perl -p -i -e 's/^(>.*)/$1;/' mybacteria.fa

Input
>Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
>Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG
A

Output
>Bacteria;Cyanobacteriales;Phormidiaceae;Lyngbya PCC-7419;Lyngbya sp. PCC 8106;
GGAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUCUGCUUAACACAUGCAAGUCGAACGGACUCUUCGGAGUUAGU
>Bacteria;Cyanobacteriales;Nostocaceae;Nodularia PCC-9350;Nodularia spumigena CCY9414;
GAGAGUUUGAUCCUGGCUCAGGAUGAACGCUGGCGGUAUGCUUAACACAUGCAAGUCGAACGGUCUCUUCGGAGAUAGUG

Details I copy pasted your first code into a file mybacteria.fa then ran the Perl pie script. Perl pie is very quick, there alternative regexs (regular expressions) that would be slightly more efficient, but Perl pie is fast regardless. In fact you don't need to use regex in this example and would be faster via a if $line == '>'; declaration (certainly true for Pythonic equivalents if line == '>') but it doesn't offer the ease and flexibility, which is combined with speed, that Perl pie does. The code will work in Linux (any flavour/flavor) or Mac OSX Darwin (i.e. Terminal app)

> **Comments:**
> **username_4**: It will work on any flavour/flavor so long as Perl is installed. Note that not all distributions ship with Perl pre-installed. Also, the capture group is not necessary - all that's needed here is: `perl -pe 's/$/;/ if /^>/' in.fa > out.fa`. Note that using `-i` without an extension will modify the input file in-place without making a backup of the original.  
> **username_8**: In fairness I did point that out in the discussion below the code. The efficiencies are generally not noticeable. However, most regex manipulations take place within the string rather than at the end requested here, and capture can be one way to deal with different situations beyond this one.  
> **username_8**: Fair point. Perl is included in most popular Linux versions including Ubuntu, Debian and Suse. Perl isn't preinstalled on RedHat or freeBSD after release 5 and nobody uses Kali in bioinformatics. Let me know if there's anything missed.  
> **username_0**: Thank you very much -- this worked well and was simple to execute.  
> **username_9**: @CallahanMcGovern if an answer worked for you, can you please mark it as accepted?  

---

### Answer by username_1 on 2022-04-05. Score: 3

I recommend to use Biopython as a clearer way.
from Bio import SeqIO

records = []
for record in SeqIO.parse("file.fas", "fasta"):
    record.description += ";"
    records.append(record)
SeqIO.write(records, "file.fas", "fasta")

Before:
>OK087550.1 Procyon lotor isolate Plo1 cytochrome b gene, partial cds; mitochondrial
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAGATCGCAACAG
GTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCATCAGTGACCCACATTTGCCG
AGATGTAAATTATGGCTGAATTATCCGATATATACACGCTAACGGAGCTTCTATATTCTTTATATGCCTA
TTCTTACACGTAGGACGAGGCTTATACTATGGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTA
TTTTACTACTCACAGTAATAGCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTG
AGGAGCAACAGTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATTCTACCATTTA
TTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGATCCAATAATCCTGCTGGAAT
TACATCAGAATCTGACAAAATTCCATTTCACCCATACTACACCATTAAAGACATTCTGGGAATCCTATTC
CTTATTTTTATACTTATAGGTTTAGTGCTATTTACGCCAGACCTACTAGGAGACCCAGATAACTACACAC
CCGCCAACCCCTTAAGCACCCCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCT
ACGTTCCATTCCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCATTCTGATTCC
TAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAATATCCCTTCATCATCATCGG
CCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTCCT

>OK087549.1 Procyon lotor isolate Plo17 cytochrome b gene, partial cds; mitochondrial
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAGATCGCAACAG
GTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCATCAGTGACCCACATTTGCCG
AGATGTAAATTATGGCTGAATTATCCGATATATACACGCTAACGGAGCTTCTATATTCTTTATATGCCTA
TTCTTACACGTAGGACGAGGCTTATACTATGGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTA
TTTTACTACTCACAGTAATAGCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTG
AGGAGCAACAGTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATTCTACCATTTA
TTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGATCCAATAATCCTGCTGGAAT
TACATCAGAATCTGACAAAATTCCATTTCACCCATACTACACCATTAAAGACATTCTGGGAATCCTATTC
CTTATTTTTATACTTATAGGTTTAGTGCTATTTACGCCAGACCTACTAGGAGACCCAGATAACTACACAC
CCGCCAACCCCTTAAGCACCCCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCT
ACGTTCCATTCCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCATTCTGATTCC
TAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAATATCCCTTCATCATCATCGG
CCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTCCT

>OK087548.1 Procyon lotor isolate Plo11 cytochrome b gene, partial cds; mitochondrial
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTTGGAATTTGTTTGCTTCTACAGATCGCAACAG
GTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCATCAGTGACCCACATTTGCCG
AGATGTAAATTATGGCTGAATTATCCGATATATACACGCTAACGGAGCTTCTATATTCTTTATATGCCTA
TTCTTACACGTAGGACGAGGCTTATACTATGGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTA
TTTTACTACTCACAGTAATAGCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTG
AGGAGCAACAGTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATTCTACCATTTA

After:
>OK087550.1 Procyon lotor isolate Plo1 cytochrome b gene, partial cds; mitochondrial;
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAG
ATCGCAACAGGTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCA
TCAGTGACCCACATTTGCCGAGATGTAAATTATGGCTGAATTATCCGATATATACACGCT
AACGGAGCTTCTATATTCTTTATATGCCTATTCTTACACGTAGGACGAGGCTTATACTAT
GGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTATTTTACTACTCACAGTAATA
GCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTGAGGAGCAACA
GTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATT
CTACCATTTATTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGA
TCCAATAATCCTGCTGGAATTACATCAGAATCTGACAAAATTCCATTTCACCCATACTAC
ACCATTAAAGACATTCTGGGAATCCTATTCCTTATTTTTATACTTATAGGTTTAGTGCTA
TTTACGCCAGACCTACTAGGAGACCCAGATAACTACACACCCGCCAACCCCTTAAGCACC
CCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCTACGTTCCATT
CCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCA
TTCTGATTCCTAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAA
TATCCCTTCATCATCATCGGCCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTC
CT
>OK087549.1 Procyon lotor isolate Plo17 cytochrome b gene, partial cds; mitochondrial;
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTCGGAATTTGTTTGCTTCTACAG
ATCGCAACAGGTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCA
TCAGTGACCCACATTTGCCGAGATGTAAATTATGGCTGAATTATCCGATATATACACGCT
AACGGAGCTTCTATATTCTTTATATGCCTATTCTTACACGTAGGACGAGGCTTATACTAT
GGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTATTTTACTACTCACAGTAATA
GCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTGAGGAGCAACA
GTAATTACAAATCTCCTGTCAGCTATCCCCTATATCGGATCTAACCTTGTAGAATGAATT
TGAGGAGGGTTTTCAGTAGACAAAGCCACCCTAACACGATTCTTCGCATTCCACTTCATT
CTACCATTTATTATCACAACGCTAGCAATAATTCACCTGCTATTCCTACACGAAACAGGA
TCCAATAATCCTGCTGGAATTACATCAGAATCTGACAAAATTCCATTTCACCCATACTAC
ACCATTAAAGACATTCTGGGAATCCTATTCCTTATTTTTATACTTATAGGTTTAGTGCTA
TTTACGCCAGACCTACTAGGAGACCCAGATAACTACACACCCGCCAACCCCTTAAGCACC
CCACCTCACATTAAACCTGAATGATATTTTCTATTCGCCTACGCAATTCTACGTTCCATT
CCCAACAAACTAGGAGGAGTCCTAGCCCTAGTCCTCTCCATCTTAATCCTAATCATCATC
CCACTCCTACATACCTCAAAACAACGAAGCATAATATTTCGGCCACTTAGCCAATGTTCA
TTCTGATTCCTAGTAGCAGACCTCCTCGTCCTAACATGAATTGGAGGTCAACCAGTAGAA
TATCCCTTCATCATCATCGGCCAACTAGCCTCCATCTTCTACTTTATAATCCTCCTGGTC
CT
>OK087548.1 Procyon lotor isolate Plo11 cytochrome b gene, partial cds; mitochondrial;
TCAAACATCTCAGCATGATGAAATTTCGGCTCCCTCCTTGGAATTTGTTTGCTTCTACAG
ATCGCAACAGGTTTATTCTTAGCCATGCACTATACACCAGATACAACCACAGCTTTCTCA
TCAGTGACCCACATTTGCCGAGATGTAAATTATGGCTGAATTATCCGATATATACACGCT
AACGGAGCTTCTATATTCTTTATATGCCTATTCTTACACGTAGGACGAGGCTTATACTAT
GGCTCCTATACATTCTCTGAAACATGAAATATTGGTGTTATTTTACTACTCACAGTAATA
GCAACCGCTTTCATAGGTTACGTCCTCCCATGAGGACAAATATCATTCTGAGGAGCAACA

> **Comments:**
> **username_2**: Clearer than what? Why is using a complex package requiring several lines of code "clearer" than using standard *nix tools and one liners?  
> **username_1**: @terdon For the same reasons fasta, nexus, &c. are explicit. It is easier to read at a glance.  
> **username_2**: I find this much harder to read than the standard tools with their simple syntax. I need to grok 6 lines of code here _and_ manually enter the file name twice with no autocompletion. You also don't mention that you need to install biopython, while the other solutions work out of the box on pretty much any *nix system. On the whole, this is longer, more complex, less portable and significantly slower than either the perl or sed one-liners. This took 6.7s compared to 2s for Perl and 1.6s for sed on a ~300MB file. It does work, but let's stick to the technical and remove the opinion :).  
> **username_1**: @terdon Of course, you are right from this side. But it reminds me the times when I have only 105 bytes of programme memory & try use the address byte of GOTO as hex-command forwarding on it from another GOTO because it was more effective :-)  
> **username_2**: Heh, fair. But I just honestly don't find this in any way clearer. It certainly took me more seconds to understand this than any of the other answers. You are obviously more used to python than to perl or sed, so of course you will find it clearer. I am familiar with python, perl and sed, and of the three solutions, this was the least clear since it had more text to read. Everyone's experience is different! :)  
> **username_3**: @terdon As someone who has taught programming to juniors I would bet a significant amount of money that a larger percentage of 'people in IT' will correctly "decode" what this does compared to any regex based solution. The strength of regexes is their flexibility, not their cleanness or readability. Appending a character at the end of a line really isn't playing to the strengths of regexes.  
> **username_2**: @DavidMulder oh sure, _programmers_ are more likely to be familiar with python, no question about that. Old school bioinformaticians/*nix geeks like myself, less so. In any case, it was the unsubstantiated "clearer" that rubbed me the wrong way, since it is so very subjective and happens to be wrong in my own case.  And it also feels like using a tank to swat a fly: we're loading all sorts of fancy tools that just make this a slower, less efficient solution.  
> **username_4**: @DavidMulder I'm with @terdon on this one - I don't find this solution clearer at all. It might appear easier to read at a glance, perhaps because `record.description += ";"` seems rather innocuous, but what happens if we're now presented with a FASTA file without a description field? Well, you need to know that in this case the description attribute is actually assigned the record id/name. So appending a semicolon to the description attribute will actually _create_ a description field in the output file, basically duplicating the record id/name. Probably not what anyone expected or wanted.  
> **username_5**: **Steve's point deserves emphasis.** I love Biopython but its implementation of the `id` versus `description` attributes on SeqRecord objects never fails to trip me up.  
> **username_6**: This script loads all sequences into memory, which wouldn't work for huge input.  

---

### Answer by username_7 on 2023-07-10. Score: 3

seqkit replace -p "$" -r ";" my.fasta > my.renamed.fasta


Where -p is the pattern to match the end of the header text $
Where -r is the replacement pattern

https://bioinf.shenwei.me/seqkit/usage/#replace
Seqkit is an extremely powerful toolkit for working with fasta/fastq files. It can a lot with a single cli command.


---

