Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-24T21:03:19.187Z
Answers.LastActivityDate: 2023-07-24T21:03:19.187Z
Answers.UserDisplayName: user172818
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-07-24T13:24:13.563Z
Comments.Text: 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.
Comments.UserDisplayName: M__
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-07-24T14:32:50.017Z
Comments.Text: 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.
Comments.UserDisplayName: ATpoint
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-07-24T17:25:43.517Z
Comments.Text: 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'`
Comments.UserDisplayName: papabiceps
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-07-24T17:31:06.437Z
Comments.Text: Julia is supposed to be fast (never used it). samtools will be faster.
Comments.UserDisplayName: M__
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-05-16T08:51:13.483Z
Comments.Text: 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.
Comments.UserDisplayName: darked89
Tags: <sam><samtools>
Title: How to reduce BAM
ThreadText: # 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 @username_2 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:
  
  ```sh
  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](https://invisible-island.net/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.
  
  
  ---
  
  