<pre><code>awk 'BEGIN{FS="::"}{if(<span class="math-container">$1~"&gt;"){printf("&gt;%s_%s\n",$2,substr($1,2))}else{print $</span>0}}' input_file.fa &gt; output.fa
</code></pre>

<p>An explanation of the non-obvious bits:</p>

<ul>
<li><code>BEGIN{FS="::"}</code> split columns using :: as the designator</li>
<li><code>$1~"&gt;"</code> If there's a > in the line</li>
<li><code>substr($1,2)</code> Trim the <code>&gt;</code> that was at the beginning of the line.</li>
</ul>

CC BY-SA 4.0
2020-05-25T12:49:21.187Z
`awk -F:: '{sub(/>/, ">" $2 "_"); print}' KDM4A_1kbp_TSS.fasta > KDM4A_1kbp_TSS_swp.fasta
        sed 's/::chr.*)//' KDM4A_1kbp_TSS_swp.fasta > KDM4A_1kbp_TSS_MEMEinput.fasta` I just checked your answer now. I had tried working by myself and come up with this script. But, yours looks much better than mine :) I appreciate it for your answer.
taeju
CC BY-SA 4.0
2020-05-24T21:57:05.610Z
2020-05-24T21:57:05.610Z
Devon Ryan
<p><code>sed -E 's/&gt;(.+)::(.+)/&gt;\2_\1/' in.fa &gt; out.fa</code> </p>

<p>If you want to use sed. </p>

CC BY-SA 4.0
2020-05-25T13:00:39.160Z
Sorry there was a little typo. Now it should work properly
Mr_Z
CC BY-SA 4.0
2020-05-25T12:51:09.417Z
2020-05-26T09:25:41.753Z
2020-05-26T09:25:41.753Z
Mr_Z
<p>I would use <code>perl</code> here instead of <code>sed</code> so you can use non-greedy patterns (e.g. <code>.*?</code>) and so ensure that you always match the <em>first</em> occurrence of <code>::</code> if there are more than one on the line. Perl also has <code>-i</code>, and in fact is where sed got the idea from, so you can edit the file in place just like you can with <code>sed</code>. </p>

<p>Using this example file:</p>

<pre><code>$ cat file.fa
&gt;ENST00000488147.1::chr1:29570-30013(-)
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
&gt;ENST00000405392.5::chr2:24919186-24920186(-)
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC
</code></pre>

<p>You can do:</p>

<pre><code><span class="math-container">$ perl -pe 's/&gt;(.+?)::(.*)/&gt;$</span>2_$1/' file.fa 
&gt;chr1:29570-30013(-)_ENST00000488147.1
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
&gt;chr2:24919186-24920186(-)_ENST00000405392.5
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC
</code></pre>

<p>Or, to edit the file in place:</p>

<pre><code><span class="math-container">$ perl -i -pe 's/&gt;(.+?)::(.*)/&gt;$</span>2_<span class="math-container">$1/' file.fa 
$</span> cat file.fa
&gt;chr1:29570-30013(-)_ENST00000488147.1
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
&gt;chr2:24919186-24920186(-)_ENST00000405392.5
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC
</code></pre>

<h3>Explanation</h3>

<ul>
<li><code>perl -pe</code>: <strong>p</strong>rint each line of the input file after applying the script given by <code>-e</code> to it. </li>
<li><code>s/&gt;(.+?)::(.*)/&gt;$2_$1/'</code>: the <code>s/old/new/</code> is the substitution operator and will replace <code>old</code> with <code>new</code>. Here, we look for the shortest stretch of one or more characters (<code>.+?</code>) from the <code>&gt;</code> until the first occurrence of <code>::</code>, and capture it as <code>$1</code> (because the pattern is in parentheses). Everything after the first <code>::</code> is then captured as <code>$2</code> (<code>(.*)</code>). Then, we replace everything we matched with a <code>&gt;</code>, then the 2nd captured pattern, an underscore and the first captured pattern.</li>
</ul>

<hr>

<p>Just for fun, here's a golfed awk approach:</p>

<pre><code><span class="math-container">$ awk -F'::' '$</span>0=sub(/&gt;/,"")?"&gt;"<span class="math-container">$2"_"$</span>1:$0' file.fa
&gt;chr1:29570-30013(-)_ENST00000488147.1
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
&gt;chr2:24919186-24920186(-)_ENST00000405392.5
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC
</code></pre>

CC BY-SA 4.0
2020-05-26T09:32:54.417Z
2020-05-26T09:40:26.040Z
2020-05-26T09:40:26.040Z
terdon
<p>I need to rename the following headers from a FASTA file. Something like:</p>

<pre><code>&gt;ENST00000488147.1::chr1:29570-30013(-)
&gt;ENST00000405392.5::chr2:24919186-24920186(-)
</code></pre>

<p>into different format like this:</p>

<pre><code>&gt;chr1:29570-30013(-)_ENST00000488147.1
&gt;chr2:24919186-24920186(-)_ENST00000405392.5
</code></pre>

<p>How can I rename the FASTA headers, perhaps using <code>sed</code> or <code>awk</code>?</p>

CC BY-SA 4.0
2020-05-24T20:16:05.817Z
Is there fasta sequence between the headers? If so is it multiline or single line fasta? Also what about Biopython?
M__
CC BY-SA 4.0
2020-05-25T12:42:57.103Z
Hi Michael. Yes, there are fasta sequences between the headers, and it has a large number of fasta sequences alongside their headers for each. I didn't know anything about Biopython, but I just looked it up and it seems really helpful as it has motif analysis tools (MEME or MAST). Thank you
taeju
<fasta><bash><linux>
Edit FASTA header using sed
# Edit FASTA header using sed

(Asked by: username_0 on 2020-05-24)

I need to rename the following headers from a FASTA file. Something like:
>ENST00000488147.1::chr1:29570-30013(-)
>ENST00000405392.5::chr2:24919186-24920186(-)

into different format like this:
>chr1:29570-30013(-)_ENST00000488147.1
>chr2:24919186-24920186(-)_ENST00000405392.5

How can I rename the FASTA headers, perhaps using sed or awk?

**Tags:** fasta, bash, linux
> **Comments:**
> **username_1**: Is there fasta sequence between the headers? If so is it multiline or single line fasta? Also what about Biopython?  
> **username_0**: Hi Michael. Yes, there are fasta sequences between the headers, and it has a large number of fasta sequences alongside their headers for each. I didn't know anything about Biopython, but I just looked it up and it seems really helpful as it has motif analysis tools (MEME or MAST). Thank you  

---

## 3 answers

### Answer by username_2 on 2020-05-24. Score: 8

awk 'BEGIN{FS="::"}{if($1~">"){printf(">%s_%s\n",$2,substr($1,2))}else{print $0}}' input_file.fa > output.fa

An explanation of the non-obvious bits:

BEGIN{FS="::"} split columns using :: as the designator
$1~">" If there's a > in the line
substr($1,2) Trim the > that was at the beginning of the line.

> **Comments:**
> **username_0**: `awk -F:: '{sub(/>/, ">" $2 "_"); print}' KDM4A_1kbp_TSS.fasta > KDM4A_1kbp_TSS_swp.fasta         sed 's/::chr.*)//' KDM4A_1kbp_TSS_swp.fasta > KDM4A_1kbp_TSS_MEMEinput.fasta` I just checked your answer now. I had tried working by myself and come up with this script. But, yours looks much better than mine :) I appreciate it for your answer.  

---

### Answer by username_3 on 2020-05-25. Score: 3

`sed -E 's/>(.+)::(.+)/>\2_\1/' in.fa > out.fa`

If you want to use sed.

> **Comments:**
> **username_3**: Sorry there was a little typo. Now it should work properly  

---

### Answer by username_4 on 2020-05-26. Score: 2

I would use perl here instead of sed so you can use non-greedy patterns (e.g. .*?) and so ensure that you always match the first occurrence of :: if there are more than one on the line. Perl also has -i, and in fact is where sed got the idea from, so you can edit the file in place just like you can with sed. 
Using this example file:
$ cat file.fa
>ENST00000488147.1::chr1:29570-30013(-)
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
>ENST00000405392.5::chr2:24919186-24920186(-)
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC

You can do:
$ perl -pe 's/>(.+?)::(.*)/>$2_$1/' file.fa 
>chr1:29570-30013(-)_ENST00000488147.1
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
>chr2:24919186-24920186(-)_ENST00000405392.5
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC

Or, to edit the file in place:
$ perl -i -pe 's/>(.+?)::(.*)/>$2_$1/' file.fa 
$ cat file.fa
>chr1:29570-30013(-)_ENST00000488147.1
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
>chr2:24919186-24920186(-)_ENST00000405392.5
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC

Explanation

perl -pe: print each line of the input file after applying the script given by -e to it. 
s/>(.+?)::(.*)/>$2_$1/': the s/old/new/ is the substitution operator and will replace old with new. Here, we look for the shortest stretch of one or more characters (.+?) from the > until the first occurrence of ::, and capture it as $1 (because the pattern is in parentheses). Everything after the first :: is then captured as $2 ((.*)). Then, we replace everything we matched with a >, then the 2nd captured pattern, an underscore and the first captured pattern.


Just for fun, here's a golfed awk approach:
$ awk -F'::' '$0=sub(/>/,"")?">"$2"_"$1:$0' file.fa
>chr1:29570-30013(-)_ENST00000488147.1
ACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGCACCTCTGAGAGC
ATATATCGGCATATATCGGCATATATCGGCATATATCGGCATATATCG
>chr2:24919186-24920186(-)_ENST00000405392.5
ACTCTAGGATATCGCGATATCGCCTTAGGCTAGAATCGGCTTAGC
TCGCGATATCATCGCCTTAGGCTAGAATCGTCTAGGATATCGCG
CCTTAGGCTATCATCGCCTAGAATCGTCTAGGATATCGAATC


---

