Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T08:35:29.437Z
Answers.Text: Clearer than what? Why is using a complex package requiring several lines of code "clearer" than using standard *nix tools and one liners?
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T09:29:09.543Z
Answers.Text: @terdon For the same reasons fasta, nexus, &c. are explicit. It is easier to read at a glance.
Answers.UserDisplayName: Vovin
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T09:52:13.050Z
Answers.Text: 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 :).
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T09:59:58.697Z
Answers.Text: @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 :-)
Answers.UserDisplayName: Vovin
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T10:09:12.850Z
Answers.Text: 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! :)
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T12:30:39.440Z
Answers.Text: @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.
Answers.UserDisplayName: David Mulder
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T12:42:49.360Z
Answers.Text: @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.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T14:13:51.793Z
Answers.Text: @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.
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T14:41:44.533Z
Answers.Text: **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.
Answers.UserDisplayName: Jesse
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T23:21:30.680Z
Answers.Text: This script loads all sequences into memory, which wouldn't work for huge input.
Answers.UserDisplayName: user172818
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-05T17:38:56.023Z
Answers.LastActivityDate: 2022-04-05T17:38:56.023Z
Answers.UserDisplayName: Vovin
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-10T16:39:27.927Z
Answers.LastActivityDate: 2023-07-10T16:39:27.927Z
Answers.UserDisplayName: Ammar
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T02:39:53.477Z
Answers.LastActivityDate: 2022-04-06T11:19:42.127Z
Answers.LastEditDate: 2022-04-06T11:19:42.127Z
Answers.UserDisplayName: Steve
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-09T20:30:15.850Z
Answers.Text: @CallahanMcGovern if an answer worked for you, can you please mark it as accepted?
Answers.UserDisplayName: gringer
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T02:50:45.657Z
Answers.Text: 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.
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T11:34:50.837Z
Answers.Text: 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.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-06T12:15:07.307Z
Answers.Text: 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.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-07T00:46:57.137Z
Answers.Text: Thank you very much -- this worked well and was simple to execute.
Answers.UserDisplayName: Callahan McGovern
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-05T17:00:46.050Z
Answers.LastActivityDate: 2022-04-06T08:40:21.867Z
Answers.LastEditDate: 2022-04-06T08:40:21.867Z
Answers.UserDisplayName: M__
Body: <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>
  
Tags: <phylogenetics><fasta><phylogeny><bash><bacteria>
Title: How can I add a ";" at the end of each fasta header line in a file?
ThreadText: # 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](/questions/tagged/sed "show questions tagged 'sed'") and a regex [address](https://www.gnu.org/software/sed/manual/html_node/Addresses.html) 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](/questions/tagged/awk "show questions tagged '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](/questions/tagged/perl "show questions tagged '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**: @username_0 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**: @username_2 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**: @username_2 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**: @username_2 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**: @username_3 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**: @username_3 I'm with @username_2 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**: **username_4'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.
  
  
  ---
  
  