Answers.Body: <p>I like using <code>awk</code> when there's any kind of lookup involved: something like</p>
  
  <pre><code>awk 'FNR==NR {
      hash["&gt;"$1]=$2;
      next;
  }
  
  if ($1 ~ /^&gt;/) {
      print "&gt;"hash[$1];
  } else {
      print $1;
  }' keyValues.txt mySequence.fasta
  </code></pre>
  
  <p>Basically the <code>FNR==NR</code> check tells awk to work only on the first file (useful primer <a href="https://stackoverflow.com/questions/32481877/what-is-nr-fnr-in-awk">here</a>), <code>keyValues.txt</code> and create an association for each key (eg. <code>chr_I</code>) with its value (eg. <code>I</code>). The rest of the code after the <code>next</code> works only on <code>mySequence.fasta</code>, printing out the lookup value only if the line is a fasta header, as checked by the <code>$1 ~ /^&gt;/</code> condition. </p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-27T17:41:48.223Z
Answers.LastActivityDate: 2018-06-27T17:41:48.223Z
Answers.UserDisplayName: flatley176
Answers.Body: <p>Your issue is that the pattern <code>.</code> matches a single character. To match the whole header, use <code>.*</code>:</p>
  <pre class="lang-sh prettyprint-override"><code>seqkit replace -p &quot;(.*)&quot; --replacement &quot;{kv}&quot; --kv-file keyValues.txt mySequence.fasta
  </code></pre>
  <p>Alternatively as pointed out by others you may not really need <code>keyValues.txt</code> here as you're just removing the <code>chr_</code> prefix:</p>
  <pre class="lang-sh prettyprint-override"><code>seqkit replace -p &quot;chr_(.*)&quot; --replacement '$1' mySequence.fasta
  </code></pre>
  <p>(Don't forget the single quotes for <code>$1</code> else the shell will expand it)</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-04-22T07:55:29.393Z
Answers.LastActivityDate: 2023-04-22T07:55:29.393Z
Answers.UserDisplayName: bricoletc
Answers.Body: <p>Here is an alternative to sed: <code>cat test | tr -d "chr_"</code></p>
  
  <p>The pipe is to output the file, while the <code>tr</code> command is to translate and change the file</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-25T10:20:09.410Z
Answers.Text: The use of the `cat` command is completely redundant here (and imposes a runtime overhead). Just do `tr -d 'chr_' < test`.
Answers.UserDisplayName: Konrad Rudolph
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-24T17:38:12.380Z
Answers.LastActivityDate: 2018-06-25T07:58:30.013Z
Answers.LastEditDate: 2018-06-25T07:58:30.013Z
Answers.UserDisplayName: aerijman
Answers.Body: <p>Why not use <code>sed</code> instead?</p>
  
  <pre><code>sed -e 's/chr_I/I/' -e 's/chr_V/V/' -e 's/chr_X/X/' mySequence.fasta &gt; mySeq.fasta
  </code></pre>
  
  <p>Or even simpler:</p>
  
  <pre><code>sed 's/chr_//' mySequence.fasta &gt; mySeq.fasta
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-21T12:12:24.260Z
Answers.Text: Worked. I just don't know `sed`. I need to learn it.
Answers.UserDisplayName: Biomagician
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-21T12:16:30.090Z
Answers.Text: Great! It works a bit like `grep` (which you know how to use), but then with replacement function.
Answers.UserDisplayName: benn
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-21T16:00:07.283Z
Answers.Text: I would suggest using `sed 's/^chr_//'` instead. Anchoring the pattern to the beginning of the line should speed things up for large files. Otherwise, `sed` will have to scan the entire length of each line in case there's a match.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-21T17:21:57.323Z
Answers.Text: @terdon, good point. But does it work with fasta? Remember the `>` at the beginning of the header.
Answers.UserDisplayName: benn
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-21T22:09:10.217Z
Answers.Text: @b.nota Duh! I should learn to read :) Indeed, `sed 's/^>chr_/>/` would be better.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-22T05:46:39.750Z
Answers.Text: Minor correction for the last: `sed 's/^>chr_/>/'` ( in order to keep the `>`)
Answers.UserDisplayName: Sebastian Müller
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-21T12:09:36.550Z
Answers.LastActivityDate: 2018-06-21T12:39:35.483Z
Answers.LastEditDate: 2018-06-21T12:39:35.483Z
Answers.UserDisplayName: benn
Body: <p>I am trying to use the <a href="https://bioinf.shenwei.me/seqkit/usage/#replace" rel="noreferrer">seqkit replace</a> command to replace chromosome names in the format <code>chr_I, chr_II, ...</code> to <code>I, II, ...</code>. I am using the following command:</p>
  <pre><code>seqkit replace -p &quot;(.)&quot; --replacement &quot;{kv}&quot; --kv-file keyValues.txt mySequence.fasta
  </code></pre>
  <p>My <code>keyValues.txt</code> file contains the following:</p>
  <pre><code>chr_I   I
  chr_II  II
  ...
  </code></pre>
  <p>The two columns are separated by a tabulation.</p>
  <p>I get the following output:</p>
  <pre><code>[INFO] read key-value file: keyValues.txt
  [INFO] 6 pairs of key-value loaded
  [ERRO] pattern &quot;(.)&quot; matches multiple targets in &quot;chr_I&quot;, this will cause chaos
  </code></pre>
  <p>I don't know what I am doing wrong. I chose the <code>(.)</code> pattern to match the whole header but it seems to be wrong. Any help would be appreciated.</p>
  <h3>Update</h3>
  <p>All the headers are shown below:</p>
  <pre><code>grep '&gt;' mySequence.fasta
  &gt;chr_I
  &gt;chr_II
  &gt;chr_III
  &gt;chr_IV
  &gt;chr_V
  &gt;chr_X
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-21T10:38:48.360Z
Comments.Text: Show some of the headers, the pattern argument is probably not suitable. I am guessing that you'll get headers with duplicate names now (which `will cause chaos`).
Comments.UserDisplayName: benn
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-21T11:25:01.887Z
Comments.Text: I have written all the header names in my question.
Comments.UserDisplayName: Biomagician
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-21T11:38:43.830Z
Comments.Text: There are 4 matches to your pattern "chr_I"
Comments.UserDisplayName: benn
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-06-21T12:10:31.913Z
Comments.Text: Oh, so the key is a regular expression? I tried putting a dollar at the end of the key names, but I get the same error.
Comments.UserDisplayName: Biomagician
Tags: <fasta>
Title: How do I rename fasta headers?
ThreadText: # How do I rename fasta headers?
  
  (Asked by: username_0 on 2018-06-21)
  
  I am trying to use the [seqkit replace](https://bioinf.shenwei.me/seqkit/usage/#replace) command to replace chromosome names in the format `chr_I, chr_II, ...` to `I, II, ...`. I am using the following command:
  
  ```
  seqkit replace -p "(.)" --replacement "{kv}" --kv-file keyValues.txt mySequence.fasta
  
  ```
  
  My `keyValues.txt` file contains the following:
  
  ```
  chr_I   I
  chr_II  II
  ...
  
  ```
  
  The two columns are separated by a tabulation.
  
  I get the following output:
  
  ```
  [INFO] read key-value file: keyValues.txt
  [INFO] 6 pairs of key-value loaded
  [ERRO] pattern "(.)" matches multiple targets in "chr_I", this will cause chaos
  
  ```
  
  I don't know what I am doing wrong. I chose the `(.)` pattern to match the whole header but it seems to be wrong. Any help would be appreciated.
  
  ### Update
  
  All the headers are shown below:
  
  ```
  grep '>' mySequence.fasta
  >chr_I
  >chr_II
  >chr_III
  >chr_IV
  >chr_V
  >chr_X
  
  ```
  
  **Tags:** fasta
  
  > **Comments:**
  > **username_1**: Show some of the headers, the pattern argument is probably not suitable. I am guessing that you'll get headers with duplicate names now (which `will cause chaos`).  
  > **username_0**: I have written all the header names in my question.  
  > **username_1**: There are 4 matches to your pattern "chr_I"  
  > **username_0**: Oh, so the key is a regular expression? I tried putting a dollar at the end of the key names, but I get the same error.  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_1 on 2018-06-21. Score: 10 | Accepted answer
  
  Why not use `sed` instead?
  
  ```
  sed -e 's/chr_I/I/' -e 's/chr_V/V/' -e 's/chr_X/X/' mySequence.fasta > mySeq.fasta
  
  ```
  
  Or even simpler:
  
  ```
  sed 's/chr_//' mySequence.fasta > mySeq.fasta
  
  ```
  
  > **Comments:**
  > **username_0**: Worked. I just don't know `sed`. I need to learn it.  
  > **username_1**: Great! It works a bit like `grep` (which you know how to use), but then with replacement function.  
  > **username_6**: I would suggest using `sed 's/^chr_//'` instead. Anchoring the pattern to the beginning of the line should speed things up for large files. Otherwise, `sed` will have to scan the entire length of each line in case there's a match.  
  > **username_1**: @username_6, good point. But does it work with fasta? Remember the `>` at the beginning of the header.  
  > **username_6**: @b.nota Duh! I should learn to read :) Indeed, `sed 's/^>chr_/>/` would be better.  
  > **username_7**: Minor correction for the last: `sed 's/^>chr_/>/'` ( in order to keep the `>`)  
  
  ---
  
  ### Answer by username_2 on 2018-06-27. Score: 2
  
  I like using `awk` when there's any kind of lookup involved: something like
  
  ```
  awk 'FNR==NR {
      hash[">"$1]=$2;
      next;
  }
  
  if ($1 ~ /^>/) {
      print ">"hash[$1];
  } else {
      print $1;
  }' keyValues.txt mySequence.fasta
  
  ```
  
  Basically the `FNR==NR` check tells awk to work only on the first file (useful primer [here](https://stackoverflow.com/questions/32481877/what-is-nr-fnr-in-awk)), `keyValues.txt` and create an association for each key (eg. `chr_I`) with its value (eg. `I`). The rest of the code after the `next` works only on `mySequence.fasta`, printing out the lookup value only if the line is a fasta header, as checked by the `$1 ~ /^>/` condition.
  
  
  ---
  
  ### Answer by username_3 on 2023-04-22. Score: 1
  
  Your issue is that the pattern `.` matches a single character. To match the whole header, use `.*`:
  
  ```sh
  seqkit replace -p "(.*)" --replacement "{kv}" --kv-file keyValues.txt mySequence.fasta
  
  ```
  
  Alternatively as pointed out by others you may not really need `keyValues.txt` here as you're just removing the `chr_` prefix:
  
  ```sh
  seqkit replace -p "chr_(.*)" --replacement '$1' mySequence.fasta
  
  ```
  
  (Don't forget the single quotes for `$1` else the shell will expand it)
  
  
  ---
  
  ### Answer by username_4 on 2018-06-24. Score: 1
  
  Here is an alternative to sed: `cat test | tr -d "chr_"`
  
  The pipe is to output the file, while the `tr` command is to translate and change the file
  
  > **Comments:**
  > **username_5**: The use of the `cat` command is completely redundant here (and imposes a runtime overhead). Just do `tr -d 'chr_' < test`.  
  
  ---
  
  