<p>One way using <a href="/questions/tagged/awk" class="post-tag" title="show questions tagged &#39;awk&#39;" rel="tag" aria-labelledby="awk-container">awk</a>:</p>
<pre><code>awk 'BEGIN { FS=OFS=&quot;|&quot; } /^&gt;/ { print &quot;&gt;&quot; $2, &quot;1&quot;, &quot;training&quot;; next }1' file.fa
</code></pre>
<p>This sets the <a href="https://www.gnu.org/software/gawk/manual/html_node/Field-Separators.html" rel="noreferrer"><em>field separator</em> (FS)</a> and the <a href="https://www.gnu.org/software/gawk/manual/html_node/Output-Separators.html" rel="noreferrer"><em>output field separator</em> (OFS)</a>  to a pipe character. Then for each header line, we can just print the fields we want. The output fields will be delimited with pipe characters since we already set <code>OFS</code> to a pipe character in the <code>BEGIN</code> block. We can use <a href="https://www.gnu.org/software/gawk/manual/html_node/Next-Statement.html" rel="noreferrer"><em>next</em></a> here to force awk to immediately stop processing the current record and move on to the next record, which is just the next line, since, by default, awk's <a href="https://www.gnu.org/software/gawk/manual/html_node/awk-split-records.html" rel="noreferrer"><em>record separator</em></a> is a newline character.</p>
<p>Since the <code>1</code> on the end just returns true, it performs the default action, which is to print the current record stored in <code>$0</code>. It is just the same as:</p>
<pre><code>awk 'BEGIN { FS=OFS=&quot;|&quot; } /^&gt;/ { print &quot;&gt;&quot; $2, &quot;1&quot;, &quot;training&quot;; next } { print $0 }'
</code></pre>
<p>Which is the same as:</p>
<pre><code>awk 'BEGIN { FS=OFS=&quot;|&quot; } /^&gt;/ { print &quot;&gt;&quot; $2, &quot;1&quot;, &quot;training&quot;; next } { print }'
</code></pre>

CC BY-SA 4.0
2022-09-01T12:41:47.583Z
Thank you @ Steve.
Amit
CC BY-SA 4.0
2022-09-04T10:34:57.913Z
Nice! You could shorten it to something like `awk -F'|' '/>/{printf ">%s|1|training\n",$2; next}1' file.fa` or even `awk -F'|' '{ (/>/) ? $0=">"$2"|1|training" : $0=$0}1' file.fa` if you want.
terdon
CC BY-SA 4.0
2022-09-01T11:19:36.463Z
2022-09-01T11:19:36.463Z
Steve
<pre><code>perl -p -i -e 's/&gt;[a-z]+?\|([A-Z]+[^\|]+?\|).*SV=([0-9]+)/&gt;<span class="math-container">$1$</span>2\|training/g' myfilename.fa
</code></pre>
<p>Not tested yet. Just check the sequence ID starts with a capital A-Z character. Probably wise to test it without the <code>-i</code></p>

CC BY-SA 4.0
2022-09-01T12:42:21.737Z
Many thanks @M_
Amit
CC BY-SA 4.0
2022-09-01T12:46:30.530Z
Thanks @user1738234 , I'll test it later. I assume that the `1` refers to the SV number. Is that correct?
M__
CC BY-SA 4.0
2022-09-01T12:39:44.120Z
2022-09-01T13:20:23.577Z
2022-09-01T13:20:23.577Z
M__
<p>Here's another simple perl solution:</p>
<pre><code>$ perl -lpe 's/\|.*(\d+)/|$1|training/ if s/&gt;.+?\|/&gt;/' file.fa 
&gt;A0A075B6G3|1|training
</code></pre>
<p>Note that you didn't tell us where the <code>1</code> came from, so I am taking the last numbers on the line, the <code>SV=1</code> in your case. If you want to hard-code the <code>1</code>, you can do so easily with:</p>
<pre><code>perl -lpe 's/\|.*/|1|training/ if s/&gt;.+?\|/&gt;/' file.fa
</code></pre>
<p>The <code>-lpe</code> options mean &quot;<strong>p</strong>rint each line, adding a new<strong>l</strong>ine character to each <code>print</code> call, after applying the script given by <code>-e</code>&quot;. So this will read the file line by line, do its thing and print the result.</p>
<p>The <code>s/old/new/</code> is the substitution operator and will replace <code>old</code> with <code>new</code>. In this case, we are replacing a <code>|</code> character (<code>\|</code>) and everything after it (<code>.*</code>) until the last set of numbers on the line which we capture and save as <code>$1</code> with <code>(\d+)</code>. This substitution will only happen if we have already successfully substituted the leading <code>&gt;</code> and everything until the first <code>|</code> (<code>&gt;.+?\|</code>) with just a <code>&gt;</code>.</p>
<p>If you want to edit the original file in place, use the <code>-i</code> flag (but give it a value, <code>.bak</code> in the example below, since that ensures a backup file with the original data and that extension will be created):</p>
<pre><code>perl -i .bak -lpe 's/\|.*(\d+)/|$1|training/ if s/&gt;.+?\|/&gt;/' file.fa 
</code></pre>

CC BY-SA 4.0
2022-09-04T10:18:53.820Z
2022-09-04T10:27:32.450Z
2022-09-04T10:27:32.450Z
terdon
<p>I have a FASTA file with 97,000 entires arranged like this :</p>
<pre><code>&gt;tr|A0A075B6G3|A0A075B6G3_HUMAN Dystrophin OS=Homo sapiens OX=9606 GN=DMD PE=1 SV=1
</code></pre>
<p>I want to have an output like this:</p>
<pre><code>&gt;A0A075B6G3|1|training
</code></pre>
<p>I am aware of many one liners in <code>sed</code>, <code>perl</code> and <code>awk</code> but none are working . I have something like this :</p>
<pre><code>awk '/&gt;/{$0=&quot;&gt;ID|1|training&quot;}1'
</code></pre>
<p>Kindly help.</p>

CC BY-SA 4.0
2022-09-04T10:19:59.127Z
Where is the `|1|` coming from? Is that an incrementing value that will change for each line? Is it the `PE=1`? Or maybe the `SV=1`?
terdon
<fasta><awk>
change/edit FASTA headers
# change/edit FASTA headers

(Asked by: username_0 on 2022-09-01)

I have a FASTA file with 97,000 entires arranged like this :
>tr|A0A075B6G3|A0A075B6G3_HUMAN Dystrophin OS=Homo sapiens OX=9606 GN=DMD PE=1 SV=1

I want to have an output like this:
>A0A075B6G3|1|training

I am aware of many one liners in sed, perl and awk but none are working . I have something like this :
awk '/>/{$0=">ID|1|training"}1'

Kindly help.

**Tags:** fasta, awk
> **Comments:**
> **username_1**: Where is the `|1|` coming from? Is that an incrementing value that will change for each line? Is it the `PE=1`? Or maybe the `SV=1`?  

---

## 3 answers

### Answer by username_2 on 2022-09-01. Score: 7

One way using awk:
awk 'BEGIN { FS=OFS="|" } /^>/ { print ">" $2, "1", "training"; next }1' file.fa

This sets the field separator (FS) and the output field separator (OFS)  to a pipe character. Then for each header line, we can just print the fields we want. The output fields will be delimited with pipe characters since we already set OFS to a pipe character in the BEGIN block. We can use next here to force awk to immediately stop processing the current record and move on to the next record, which is just the next line, since, by default, awk's record separator is a newline character.
Since the 1 on the end just returns true, it performs the default action, which is to print the current record stored in $0. It is just the same as:
awk 'BEGIN { FS=OFS="|" } /^>/ { print ">" $2, "1", "training"; next } { print $0 }'

Which is the same as:
awk 'BEGIN { FS=OFS="|" } /^>/ { print ">" $2, "1", "training"; next } { print }'

> **Comments:**
> **username_0**: Thank you @ Steve.  
> **username_1**: Nice! You could shorten it to something like `awk -F'|' '/>/{printf ">%s|1|training\n",$2; next}1' file.fa` or even `awk -F'|' '{ (/>/) ? $0=">"$2"|1|training" : $0=$0}1' file.fa` if you want.  

---

### Answer by username_3 on 2022-09-01. Score: 1

perl -p -i -e 's/>[a-z]+?\|([A-Z]+[^\|]+?\|).*SV=([0-9]+)/>$1$2\|training/g' myfilename.fa

Not tested yet. Just check the sequence ID starts with a capital A-Z character. Probably wise to test it without the -i

> **Comments:**
> **username_0**: Many thanks @M_  
> **username_3**: Thanks @user1738234 , I'll test it later. I assume that the `1` refers to the SV number. Is that correct?  

---

### Answer by username_1 on 2022-09-04. Score: 1

Here's another simple perl solution:
$ perl -lpe 's/\|.*(\d+)/|$1|training/ if s/>.+?\|/>/' file.fa 
>A0A075B6G3|1|training

Note that you didn't tell us where the 1 came from, so I am taking the last numbers on the line, the SV=1 in your case. If you want to hard-code the 1, you can do so easily with:
perl -lpe 's/\|.*/|1|training/ if s/>.+?\|/>/' file.fa

The -lpe options mean "print each line, adding a newline character to each print call, after applying the script given by -e". So this will read the file line by line, do its thing and print the result.
The s/old/new/ is the substitution operator and will replace old with new. In this case, we are replacing a | character (\|) and everything after it (.*) until the last set of numbers on the line which we capture and save as $1 with (\d+). This substitution will only happen if we have already successfully substituted the leading > and everything until the first | (>.+?\|) with just a >.
If you want to edit the original file in place, use the -i flag (but give it a value, .bak in the example below, since that ensures a backup file with the original data and that extension will be created):
perl -i .bak -lpe 's/\|.*(\d+)/|$1|training/ if s/>.+?\|/>/' file.fa


---

