<p>You can edit your <code>for</code> loop so as to include the paths to your files of interest.</p>

<p>The command below will give you the relative paths (relative to where you run the command, I think it is better to run this within your <code>main</code> directory) of your files of interest:</p>

<pre><code>ls mpg*/mgm*.3/*.fna
</code></pre>

<p>You can use the output of this command (your files of interest) to iterate over via your for loop. Your code will look like:</p>

<pre><code>for i in {...}; do 
    sed -i.bak "s/^&gt;/&gt;${i}_/" i
done
</code></pre>

CC BY-SA 4.0
2019-10-02T19:49:15.980Z
Alot slicker than using Perl
M__
CC BY-SA 4.0
2019-10-03T10:45:12.213Z
Thank you! I've tried to do this. (though tried 'while' instead)

`ls mgp*/mgm*.3/*.fna | while read line ; 
do
 header=$(sed -r "s/^mgp([0-9]*)\/mgm[0-9]{4}([0-9]{1,})\.3\/(mgm.*\.fna)/\1_\2/") 
 sed -i.bak "s/^>/>${header}_/" $line
done`

It seems to only edit the first of the files I'm interested in (but it does it correctly as far as I can tell). Any idea of what could've gone wrong?
Laura
CC BY-SA 4.0
2019-10-03T12:24:17.623Z
I am not sure if you really need that complicated command within `do`, fasta headers always start with `>`, which seems to be parsed in your `sed`. My suggestion would be: `ls mgp*/mgm*.3/*.fna | while read line; do sed -i.bak "s/^>/>${i}_/" $line; done`.
haci
CC BY-SA 4.0
2019-10-07T12:01:33.720Z
I've tried. For some reason it doesn't work for me. All it does is add an underscore to the fasta headers in the edited files.
Laura
CC BY-SA 4.0
2019-10-07T13:38:28.660Z
It is because I forgot to change the  `${i}` part in `sed` while editing the code regarding your comment above with `while read`. You can do something like `${line:Ind:Len}`, `Ind` being the zero based index and `Len` is the length of the substring you would like to extract from the full file path.
haci
CC BY-SA 4.0
2019-10-02T12:14:11.787Z
2019-10-02T12:20:53.717Z
2019-10-02T12:20:53.717Z
haci
<p>This is an expansion of my previous question, <a href="https://bioinformatics.stackexchange.com/questions/10491/how-to-edit-the-headers-of-multiple-fasta-files-from-multiple-folders">How to edit the headers of multiple fasta files from multiple folders?</a></p>

<p>My directories are organized as follows: one main directory, in which I have multiple project directories. Inside each project directory, there are multiple metagenome directories. Inside each metagenome directory, there is always a single .fna (fasta) file.</p>

<p>Names: project directories start with 'mgp', metagenome directories start with 'mgm' and end with '.3'. They end in numbers, but the numbers are not related. (eg. project directory 'mgp83581' contains metagenome directory 'mgm4729322.3').</p>

<p>What I want is a loop that would go through all these fasta files, and add to the headers codes corresponding to project and metagenome directory. For example, if the fasta file in project directory mgp83581, metagenome subdirectory mgm4729322.3 had the following headers...</p>

<p><code>&gt;seq1</code></p>

<p><code>&gt;seq2</code></p>

<p>...then I would want to change it to:</p>

<p><code>&gt;83581_322_seq1</code></p>

<p><code>&gt;83581_322_seq2</code></p>

<p>Basically, I want to add the number code associated with the project, and the last three digits of the 7-digit code associated with the metagenome (apart from the '.3' part of the file name).</p>

<p>Below is the answer that I got for my previous question, where I didn't have project directories, and where the 3-digit code for the metagenomes stayed in a manageable range. (thanks terdon!)</p>

<p><code>for i in {314..727}; do 
    sed -i.bak "s/^&gt;/&gt;${i}_/" mgm4761${i}.3/*.fna
done</code></p>

<p>Using ubuntu. I would appreciate your help!</p>

<fasta><bash>
How to edit the headers of multiple fasta files from multiple folders? (recursively)
# How to edit the headers of multiple fasta files from multiple folders? (recursively)

(Asked by: username_0 on 2019-10-02)

This is an expansion of my previous question, [How to edit the headers of multiple fasta files from multiple folders?](https://bioinformatics.stackexchange.com/questions/10491/how-to-edit-the-headers-of-multiple-fasta-files-from-multiple-folders)

My directories are organized as follows: one main directory, in which I have multiple project directories. Inside each project directory, there are multiple metagenome directories. Inside each metagenome directory, there is always a single .fna (fasta) file.

Names: project directories start with 'mgp', metagenome directories start with 'mgm' and end with '.3'. They end in numbers, but the numbers are not related. (eg. project directory 'mgp83581' contains metagenome directory 'mgm4729322.3').

What I want is a loop that would go through all these fasta files, and add to the headers codes corresponding to project and metagenome directory. For example, if the fasta file in project directory mgp83581, metagenome subdirectory mgm4729322.3 had the following headers...

`>seq1`

`>seq2`

...then I would want to change it to:

`>83581_322_seq1`

`>83581_322_seq2`

Basically, I want to add the number code associated with the project, and the last three digits of the 7-digit code associated with the metagenome (apart from the '.3' part of the file name).

Below is the answer that I got for my previous question, where I didn't have project directories, and where the 3-digit code for the metagenomes stayed in a manageable range. (thanks terdon!)

`for i in {314..727}; do
sed -i.bak "s/^>/>${i}_/" mgm4761${i}.3/*.fna
done`

Using ubuntu. I would appreciate your help!

**Tags:** fasta, bash

---

## 1 answers

### Answer by username_1 on 2019-10-02. Score: 1

You can edit your for loop so as to include the paths to your files of interest.
The command below will give you the relative paths (relative to where you run the command, I think it is better to run this within your main directory) of your files of interest:
ls mpg*/mgm*.3/*.fna

You can use the output of this command (your files of interest) to iterate over via your for loop. Your code will look like:
for i in {...}; do 
    sed -i.bak "s/^>/>${i}_/" i
done

> **Comments:**
> **username_2**: Alot slicker than using Perl  
> **username_0**: Thank you! I've tried to do this. (though tried 'while' instead)  `ls mgp*/mgm*.3/*.fna | while read line ;  do  header=$(sed -r "s/^mgp([0-9]*)\/mgm[0-9]{4}([0-9]{1,})\.3\/(mgm.*\.fna)/\1_\2/")   sed -i.bak "s/^>/>${header}_/" $line done`  It seems to only edit the first of the files I'm interested in (but it does it correctly as far as I can tell). Any idea of what could've gone wrong?  
> **username_1**: I am not sure if you really need that complicated command within `do`, fasta headers always start with `>`, which seems to be parsed in your `sed`. My suggestion would be: `ls mgp*/mgm*.3/*.fna | while read line; do sed -i.bak "s/^>/>${i}_/" $line; done`.  
> **username_0**: I've tried. For some reason it doesn't work for me. All it does is add an underscore to the fasta headers in the edited files.  
> **username_1**: It is because I forgot to change the  `${i}` part in `sed` while editing the code regarding your comment above with `while read`. You can do something like `${line:Ind:Len}`, `Ind` being the zero based index and `Len` is the length of the substring you would like to extract from the full file path.  

---

