<p>You can do this easily with <a href="https://github.com/lh3/bioawk" rel="noreferrer">bioawk</a>, which is a version of awk with added features facilitating bioinformatics:</p>

<pre><code>bioawk -c fastx '{print $name"\t0\t"length($seq)}' test.fa
</code></pre>

<p><code>-c fastx</code> tells the program that the data should be parsed as fasta or fastq format. This makes the <code>$name</code> and <code>$seq</code> variables available in the awk commands.</p>

CC BY-SA 3.0
2017-05-18T11:33:23.620Z
2017-05-18T11:33:23.620Z
bli
<p>It's good practice to have your <code>FASTA</code> indexed, so you can leverage the <code>.fai</code> you are likely to already have. If not, you can just generate the index with <code>samtools</code> and use some <code>awk</code> to make your <code>BED</code>:</p>

<pre><code>samtools faidx $fasta
awk 'BEGIN {FS="\t"}; {print $1 FS "0" FS $2}' $fasta.fai &gt; $fasta.bed
</code></pre>

<p>This will maintain tab separation but you can drop the <code>BEGIN</code> statement to use spaces. The <a href="https://genome.ucsc.edu/FAQ/FAQformat.html#format1" rel="noreferrer">BED spec</a> only requires "whitespace" for the simple <code>BED</code> format.</p>

CC BY-SA 3.0
2017-05-18T08:40:08.150Z
2017-05-18T09:06:45.380Z
2017-05-18T09:06:45.380Z
Sam Nicholls
<p>Here is an approach with <a href="http://biopython.org/" rel="nofollow noreferrer"><code>BioPython</code></a>. The <code>with</code> statement ensures both the input and output file handles are closed and a <a href="https://stackoverflow.com/questions/20535342/lazy-evaluation-python"><em>lazy</em></a> approach is taken so that only a single fasta record is held in memory at a time, rather than reading the whole file into memory, which is a bad idea for large input files. The solution makes no assumptions about the sequence ID lengths or the number of lines that the sequences are spread across:</p>

<pre><code>from Bio import SeqIO

with open('sequences.fasta') as in_f, open('sequences.bed','w') as out_f:
    for record in SeqIO.parse(in_f, 'fasta'):
        out_f.write('{}\t0\t{}\n'.format(record.id, len(record)))
</code></pre>

CC BY-SA 3.0
2017-05-18T08:04:25.233Z
2017-05-18T08:56:58.783Z
2017-05-23T12:41:55.037Z
Chris_Rands
<p>Inspired by <a href="https://bioinformatics.stackexchange.com/questions/45/read-length-distribution-from-fasta-file/84#84">this answer</a> to a related question on read length distributions, you could do this with Biopython:</p>

<pre><code>from Bio.SeqIO import parse
with open("regions.bed", "w") as bed:
    for record in parse("regions.fasta", "fasta"):
        print(record.id, 0, len(record.seq), sep="\t", file=bed)
</code></pre>

CC BY-SA 3.0
2017-05-18T02:20:07.947Z
I love Python. I prefer this answer simply because it is in Python and that is what we should be using in 2017. But why does this look so much like Perl? Readability counts. I wanted to propose a cleaner snippet, but it looks like comments do not allow code. Would it be considered good tone to edit your answer?
Unknown artist
CC BY-SA 3.0
2017-05-18T02:46:07.607Z
Point taken! I've given it a go, but you're welcome to improve on it. At present there is nobody on the site with enough reputation to accept an edit. I'm happy for you to suggest an edit through comments, or edit the post and wait until someone hits 350 rep. We can delete the meta-comments after the edit is done.
Scott Gigante
CC BY-SA 3.0
2017-05-18T12:17:18.583Z
OK! I edited the answer; seems like a StackExchange-y way of doing things after all.
Unknown artist
CC BY-SA 3.0
2017-05-18T12:17:53.333Z
I too love Python, but I feel like you shouldn't need to write a script to do something as trivial as this - there are lots of command line tools that can accomplish this more quickly.
Sam Nicholls
CC BY-SA 3.0
2017-05-18T12:20:47.737Z
@SamStudio8 On the surface level, I agree. At the same time, if a person has a Python REPL constantly open (which is a lot of people), this has minimal overhead, and, in my humble opinion, quick algorithmic thinking should be promoted at all times in this profession. Moreover, if this conversion is part of a Snakemake pipeline, then it may be even more natural than calling shell() or writing a shell block.
Unknown artist
CC BY-SA 3.0
2017-05-18T12:23:57.363Z
@KirillG I usually have a REPL open, but I think I'd still favour using `awk` (or such). Years ago was a different story, but learning how to use the basics of `awk` has been one of the most productivity improving things I have done since switching to use Linux. But sure, I definitely agree if this is part of a larger script or pipeline, I wouldn't dare call `shell`. Though I'd probably use `pysam` over `biopython`, but that's just personal preference :)
Sam Nicholls
CC BY-SA 3.0
2017-05-18T13:08:48.130Z
@KirillG I wrote a BioPython solution that is arguably more readable/pythonic and doesn't put the whole input file into memory https://bioinformatics.stackexchange.com/a/106/104
Chris_Rands
CC BY-SA 3.0
2017-05-18T13:52:58.713Z
@Chris_Rands' answer is much better than mine, please upvote it!
Scott Gigante
CC BY-SA 3.0
2017-05-18T14:21:25.220Z
Thanks Scott, although with @KirillG's edit your answer is more pythonic too! However, only more recent versions of BioPython allow a string as input for `SeqIO.parse` (rather than a file handle) and I don't think BioPython ever explicitly closes the input file handle in this case?
Chris_Rands
CC BY-SA 3.0
2017-05-19T03:48:16.230Z
Hmm. Good point about Biopython version - I have only tested the most recent version on Python 2.7.11 and 3.5.1. I was a little nervous about closing file handles too, but SeqIO.parse returns a generator, not a file, so wouldn't it automatically close the handle when we reach StopIteration? (disclaimer - I have no proof of this!)
Scott Gigante
CC BY-SA 3.0
2017-05-18T01:08:32.233Z
2017-05-18T13:55:20.790Z
2017-05-18T13:55:20.790Z
Scott Gigante
<p>You could adapt this <a href="http://www.danielecook.com/generate-fasta-sequence-lengths/" rel="noreferrer">awk one-liner</a>. Note that it assumes that sequence IDs are not longer than 100 characters and that there is no description following the sequence ID on the header line.</p>

<pre><code>cat myseqs.fasta | awk '$0 ~ "&gt;" {print c; c=0;printf substr($0,2,100) "\t0\t"; } $0 !~ "&gt;" {c+=length($0);} END { print c; }'
</code></pre>

<p>Otherwise, any Bio* library (Perl, Python, Ruby) provides FASTA format parsers which will extract sequence IDs and lengths.</p>

<p>I'd point out that whilst this resembles BED it is not, strictly-speaking, since BED maps to coordinates on a chromosome or some longer sequence object.</p>

CC BY-SA 3.0
2017-05-18T01:01:14.320Z
2017-05-18T01:07:42.050Z
2017-05-18T01:07:42.050Z
neilfws
<p>If the FASTA sequences are all on a single line, then the following perl one-liner should work:</p>

<pre><code>cat myseqs.fasta | perl -ne 'if(/^&gt;([^ ]+)/){print $1} else {print " 0 ",length,"\n"}'
</code></pre>

<p>Explanation:</p>

<ul>
<li>If the line begins with a '>', then print everything up to the first space (but don't put a line break at the end)</li>
<li>Otherwise, print " 0 ", followed by the length of the line, followed by a line break</li>
</ul>

CC BY-SA 3.0
2017-05-18T01:04:48.900Z
2017-05-18T01:04:48.900Z
gringer
<p>We have many excellent answers! This will be an excellent reference for future users.</p>

<p>I found what exactly what I was asking in my question:</p>

<blockquote>
  <p><a href="https://www.biostars.org/p/191052/" rel="noreferrer">https://www.biostars.org/p/191052/</a></p>
</blockquote>

<pre><code>$ pip install pyfaidx  
$ faidx --transform bed test.fasta &gt; test.bed
</code></pre>

<p>This is the one-line command I was asking. The other answers also work, but I want to accept my own answer.</p>

CC BY-SA 3.0
2017-05-22T14:15:31.670Z
Developer of pyfaidx here. I was just about to write this answer and lament that I didn't pick a more pronounceable or memorable package name.
Matt Shirley
CC BY-SA 3.0
2017-05-19T05:14:21.100Z
2017-05-19T05:14:21.100Z
SmallChess
<p>I have a FASTA file:</p>

<pre><code>&gt; Sequence_1
GCAATGCAAGGAAGTGATGGCGGAAATAGCGTTAGATGTATGTGTAGCGGTCCC...
&gt; Sequence_2
GCAATGCAAGGAAGTGATGGCGGAAATAGCGTTAGATGTATGTGTAGCGGTCCC....
....
</code></pre>

<p>I want to generate a BED file for each sequence like:</p>

<pre><code>Sequence_1 0 1500
Sequence_2 0 1700
</code></pre>

<p>The BED regions will simply be the size of the sequences.</p>

<p><strong>Q:</strong> I did that before with a one-line command. I don't remember what that is, it was on Biostars. I can't find the post now. What's the simplest way to do the conversion?</p>

CC BY-SA 3.0
2017-05-18T00:42:17.457Z
Do you mean this biostars post? https://www.biostars.org/p/15476/
Greg
CC BY-SA 3.0
2017-05-18T00:43:10.480Z
@Greg The post doesn't give me one-line command to do what I want. I'm 100% sure I saw it somewhere on biostars a while ago, but I don't remember the name of the program that can do it.
SmallChess
CC BY-SA 3.0
2017-05-18T00:49:45.910Z
What about this one?  https://www.biostars.org/p/15476/#189089
Greg
CC BY-SA 3.0
2017-05-18T00:50:38.377Z
@Greg It was a Python program. I don't remember the name and thus no idea how to search.
SmallChess
CC BY-SA 3.0
2017-05-18T07:13:47.073Z
Would we need to create a new tag, maybe something like "format-conversion", "file-conversion"? As I expect there will be many more convert from "X to Y format" type of questions.
zx8754
<fasta><bed><file-formats><format-conversion>
How to convert FASTA to BED
# How to convert FASTA to BED

(Asked by: username_0 on 2017-05-18)

I have a FASTA file:
> Sequence_1
GCAATGCAAGGAAGTGATGGCGGAAATAGCGTTAGATGTATGTGTAGCGGTCCC...
> Sequence_2
GCAATGCAAGGAAGTGATGGCGGAAATAGCGTTAGATGTATGTGTAGCGGTCCC....
....

I want to generate a BED file for each sequence like:
Sequence_1 0 1500
Sequence_2 0 1700

The BED regions will simply be the size of the sequences.
Q: I did that before with a one-line command. I don't remember what that is, it was on Biostars. I can't find the post now. What's the simplest way to do the conversion?

**Tags:** fasta, bed, file-formats, format-conversion
> **Comments:**
> **username_1**: Do you mean this biostars post? https://www.biostars.org/p/15476/  
> **username_0**: @Greg The post doesn't give me one-line command to do what I want. I'm 100% sure I saw it somewhere on biostars a while ago, but I don't remember the name of the program that can do it.  
> **username_1**: What about this one?  https://www.biostars.org/p/15476/#189089  
> **username_0**: @Greg It was a Python program. I don't remember the name and thus no idea how to search.  
> **username_2**: Would we need to create a new tag, maybe something like "format-conversion", "file-conversion"? As I expect there will be many more convert from "X to Y format" type of questions.  

---

## 7 answers

### Answer by username_0 on 2017-05-19. Score: 7 | Accepted answer

We have many excellent answers! This will be an excellent reference for future users.
I found what exactly what I was asking in my question:

https://www.biostars.org/p/191052/

$ pip install pyfaidx  
$ faidx --transform bed test.fasta > test.bed

This is the one-line command I was asking. The other answers also work, but I want to accept my own answer.

> **Comments:**
> **username_10**: Developer of pyfaidx here. I was just about to write this answer and lament that I didn't pick a more pronounceable or memorable package name.  

---

### Answer by username_3 on 2017-05-18. Score: 15

You can do this easily with bioawk, which is a version of awk with added features facilitating bioinformatics:
bioawk -c fastx '{print $name"\t0\t"length($seq)}' test.fa

-c fastx tells the program that the data should be parsed as fasta or fastq format. This makes the $name and $seq variables available in the awk commands.


---

### Answer by username_4 on 2017-05-18. Score: 13

It's good practice to have your FASTA indexed, so you can leverage the .fai you are likely to already have. If not, you can just generate the index with samtools and use some awk to make your BED:
samtools faidx $fasta
awk 'BEGIN {FS="\t"}; {print $1 FS "0" FS $2}' $fasta.fai > $fasta.bed

This will maintain tab separation but you can drop the BEGIN statement to use spaces. The BED spec only requires "whitespace" for the simple BED format.


---

### Answer by username_8 on 2017-05-18. Score: 6

You could adapt this awk one-liner. Note that it assumes that sequence IDs are not longer than 100 characters and that there is no description following the sequence ID on the header line.
cat myseqs.fasta | awk '$0 ~ ">" {print c; c=0;printf substr($0,2,100) "\t0\t"; } $0 !~ ">" {c+=length($0);} END { print c; }'

Otherwise, any Bio* library (Perl, Python, Ruby) provides FASTA format parsers which will extract sequence IDs and lengths.
I'd point out that whilst this resembles BED it is not, strictly-speaking, since BED maps to coordinates on a chromosome or some longer sequence object.


---

### Answer by username_5 on 2017-05-18. Score: 4

Here is an approach with BioPython. The with statement ensures both the input and output file handles are closed and a lazy approach is taken so that only a single fasta record is held in memory at a time, rather than reading the whole file into memory, which is a bad idea for large input files. The solution makes no assumptions about the sequence ID lengths or the number of lines that the sequences are spread across:
from Bio import SeqIO

with open('sequences.fasta') as in_f, open('sequences.bed','w') as out_f:
    for record in SeqIO.parse(in_f, 'fasta'):
        out_f.write('{}\t0\t{}\n'.format(record.id, len(record)))


---

### Answer by username_6 on 2017-05-18. Score: 4

Inspired by this answer to a related question on read length distributions, you could do this with Biopython:
from Bio.SeqIO import parse
with open("regions.bed", "w") as bed:
    for record in parse("regions.fasta", "fasta"):
        print(record.id, 0, len(record.seq), sep="\t", file=bed)

> **Comments:**
> **username_7**: I love Python. I prefer this answer simply because it is in Python and that is what we should be using in 2017. But why does this look so much like Perl? Readability counts. I wanted to propose a cleaner snippet, but it looks like comments do not allow code. Would it be considered good tone to edit your answer?  
> **username_6**: Point taken! I've given it a go, but you're welcome to improve on it. At present there is nobody on the site with enough reputation to accept an edit. I'm happy for you to suggest an edit through comments, or edit the post and wait until someone hits 350 rep. We can delete the meta-comments after the edit is done.  
> **username_7**: OK! I edited the answer; seems like a StackExchange-y way of doing things after all.  
> **username_4**: I too love Python, but I feel like you shouldn't need to write a script to do something as trivial as this - there are lots of command line tools that can accomplish this more quickly.  
> **username_7**: @SamStudio8 On the surface level, I agree. At the same time, if a person has a Python REPL constantly open (which is a lot of people), this has minimal overhead, and, in my humble opinion, quick algorithmic thinking should be promoted at all times in this profession. Moreover, if this conversion is part of a Snakemake pipeline, then it may be even more natural than calling shell() or writing a shell block.  
> **username_4**: @KirillG I usually have a REPL open, but I think I'd still favour using `awk` (or such). Years ago was a different story, but learning how to use the basics of `awk` has been one of the most productivity improving things I have done since switching to use Linux. But sure, I definitely agree if this is part of a larger script or pipeline, I wouldn't dare call `shell`. Though I'd probably use `pysam` over `biopython`, but that's just personal preference :)  
> **username_5**: @KirillG I wrote a BioPython solution that is arguably more readable/pythonic and doesn't put the whole input file into memory https://bioinformatics.stackexchange.com/a/106/104  
> **username_6**: @Chris_Rands' answer is much better than mine, please upvote it!  
> **username_5**: Thanks Scott, although with @KirillG's edit your answer is more pythonic too! However, only more recent versions of BioPython allow a string as input for `SeqIO.parse` (rather than a file handle) and I don't think BioPython ever explicitly closes the input file handle in this case?  
> **username_6**: Hmm. Good point about Biopython version - I have only tested the most recent version on Python 2.7.11 and 3.5.1. I was a little nervous about closing file handles too, but SeqIO.parse returns a generator, not a file, so wouldn't it automatically close the handle when we reach StopIteration? (disclaimer - I have no proof of this!)  

---

### Answer by username_9 on 2017-05-18. Score: 0

If the FASTA sequences are all on a single line, then the following perl one-liner should work:
cat myseqs.fasta | perl -ne 'if(/^>([^ ]+)/){print $1} else {print " 0 ",length,"\n"}'

Explanation:

If the line begins with a '>', then print everything up to the first space (but don't put a line break at the end)
Otherwise, print " 0 ", followed by the length of the line, followed by a line break


---

