Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-09-01T12:41:47.583Z
Answers.Text: Thank you @ Steve.
Answers.UserDisplayName: Amit
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-09-04T10:34:57.913Z
Answers.Text: 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.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-09-01T11:19:36.463Z
Answers.LastActivityDate: 2022-09-01T11:19:36.463Z
Answers.UserDisplayName: Steve
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-09-01T12:42:21.737Z
Answers.Text: Many thanks @M_
Answers.UserDisplayName: Amit
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-09-01T12:46:30.530Z
Answers.Text: Thanks @user1738234 , I'll test it later. I assume that the `1` refers to the SV number. Is that correct?
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-09-01T12:39:44.120Z
Answers.LastActivityDate: 2022-09-01T13:20:23.577Z
Answers.LastEditDate: 2022-09-01T13:20:23.577Z
Answers.UserDisplayName: M__
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-09-04T10:18:53.820Z
Answers.LastActivityDate: 2022-09-04T10:27:32.450Z
Answers.LastEditDate: 2022-09-04T10:27:32.450Z
Answers.UserDisplayName: terdon
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-09-04T10:19:59.127Z
Comments.Text: 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`?
Comments.UserDisplayName: terdon
Tags: <fasta><awk>
Title: change/edit FASTA headers
ThreadText: # 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](/questions/tagged/awk "show questions tagged 'awk'"):
  
  ```
  awk 'BEGIN { FS=OFS="|" } /^>/ { print ">" $2, "1", "training"; next }1' file.fa
  
  ```
  
  This sets the [*field separator* (FS)](https://www.gnu.org/software/gawk/manual/html_node/Field-Separators.html) and the [*output field separator* (OFS)](https://www.gnu.org/software/gawk/manual/html_node/Output-Separators.html) 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*](https://www.gnu.org/software/gawk/manual/html_node/Next-Statement.html) 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*](https://www.gnu.org/software/gawk/manual/html_node/awk-split-records.html) 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 @ username_2.  
  > **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 "**p**rint each line, adding a new**l**ine 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 
  
  ```
  
  
  ---
  
  