<p>Samtools+awk:</p>
<pre class="lang-sh prettyprint-override"><code>samtools view -h aln.bam \
  | awk 'BEGIN{while((getline&lt;&quot;lineno.txt&quot;)&gt;0)a[$1]=1}/^@/{++n;print}!/^@/&amp;&amp;a[NR-n]' \
  | samtools view -b --threads=4 &gt; sub.bam
</code></pre>
<p>I would recommend <a href="https://invisible-island.net/mawk/" rel="nofollow noreferrer">mawk</a> which is much faster than other awk.</p>
<p>I believe using Julia should be faster as it would not need to convert BAM to SAM and then convert back. Five min to read through a 7GB BAM file sounds about right. That is not slow.</p>

CC BY-SA 4.0
2023-07-24T21:03:19.187Z
2023-07-24T21:03:19.187Z
user172818
<p>Consider a sorted, indexed, only mapped reads containing BAM file.</p>
<p>Is there a way to get a sub BAM based on read line numbers?</p>
<p>This can be done iteratively using a counter but its too slow. Is there a way to do this using samtools view or some tool like it.</p>

CC BY-SA 4.0
2023-07-24T13:24:13.563Z
Welcome to the site . It would be helpful to state the size of the bam file, and particularly how you did this "reiteratively" (code if possible) - is essential because samtools is not the only solution. Like did you use Python and some sort of `re`, which would explain it? Also just run time, what is slow? Finally any additional information, e.g. it's human always helps, e.g. if it turns out to be bacteria ... thats different.
M__
CC BY-SA 4.0
2023-07-24T14:32:50.017Z
Please elaborate the purpose. How would you know that something in line x,y,z, is interesting so you want to subset for it? What is the context? Is it random subsampling or specific subsampling? In the simplest case you print the bam as sam via `samtools view -h`, skip header lines, and then make sed or awk print only lines overlapping an array of numbers you define upfront. That's almost no bottleneck, it just has to go through the entire file once which is not slow.
ATpoint
CC BY-SA 4.0
2023-07-24T17:25:43.517Z
I've added more information in a edit. Can you please give me a sample code on how I can use AWK to print only lines overlapping an array of numbers.  I know to print Nth line you could do `awk 'NR==N'`
papabiceps
CC BY-SA 4.0
2023-07-24T17:31:06.437Z
Julia is supposed to be fast (never used it). samtools will be faster.
M__
CC BY-SA 4.0
2024-05-16T08:51:13.483Z
I second @ATpoint comment: selecting arbitrary lines from position sorted BAM is puzzling. If you need a random fraction of the mapped reads, there is `samtools view --subsample 0.1234 my.bam`. Selecting reads based on read/pair IDs can be done in one step.
darked89
<sam><samtools>
How to reduce BAM
# How to reduce BAM

(Asked by: username_0 on 2023-07-24)

Consider a sorted, indexed, only mapped reads containing BAM file.

Is there a way to get a sub BAM based on read line numbers?

This can be done iteratively using a counter but its too slow. Is there a way to do this using samtools view or some tool like it.

**Tags:** sam, samtools
> **Comments:**
> **username_1**: Welcome to the site . It would be helpful to state the size of the bam file, and particularly how you did this "reiteratively" (code if possible) - is essential because samtools is not the only solution. Like did you use Python and some sort of `re`, which would explain it? Also just run time, what is slow? Finally any additional information, e.g. it's human always helps, e.g. if it turns out to be bacteria ... thats different.  
> **username_2**: Please elaborate the purpose. How would you know that something in line x,y,z, is interesting so you want to subset for it? What is the context? Is it random subsampling or specific subsampling? In the simplest case you print the bam as sam via `samtools view -h`, skip header lines, and then make sed or awk print only lines overlapping an array of numbers you define upfront. That's almost no bottleneck, it just has to go through the entire file once which is not slow.  
> **username_0**: I've added more information in a edit. Can you please give me a sample code on how I can use AWK to print only lines overlapping an array of numbers.  I know to print Nth line you could do `awk 'NR==N'`  
> **username_1**: Julia is supposed to be fast (never used it). samtools will be faster.  
> **username_3**: I second @ATpoint comment: selecting arbitrary lines from position sorted BAM is puzzling. If you need a random fraction of the mapped reads, there is `samtools view --subsample 0.1234 my.bam`. Selecting reads based on read/pair IDs can be done in one step.  

---

## 1 answers

### Answer by username_4 on 2023-07-24. Score: 4 | Accepted answer

Samtools+awk:
samtools view -h aln.bam \
  | awk 'BEGIN{while((getline<"lineno.txt")>0)a[$1]=1}/^@/{++n;print}!/^@/&&a[NR-n]' \
  | samtools view -b --threads=4 > sub.bam

I would recommend mawk which is much faster than other awk.
I believe using Julia should be faster as it would not need to convert BAM to SAM and then convert back. Five min to read through a 7GB BAM file sounds about right. That is not slow.


---

