4
$\begingroup$

I found here this awk script:

BEGIN {
  headertype="";
  }
{
  if($0 ~ "^@") {
    countread++;
    headertype="@";
  }
  else if($0 ~ "^+") {
    headertype="+";
  }
  else if(headertype="@") { # This is a nuc sequence
    len=length($0);
    if (len>4) {
      readlength[len]++;
    }
  }
}
END {
  for (i in readlength){
    countstored+=readlength[i];
    lensum+=readlength[i]*i;
    print i, readlength[i];
  }
  print "reads read = "countread > "/dev/stderr";
  print "reads stored = "countstored > "/dev/stderr";
  print "read average length = "lensum/countstored > "/dev/stderr";
}

and I just wonder if it is possible to shorten it with bioawk?

$\endgroup$
2
  • 3
    $\begingroup$ It might be possible. What problem do you have with having a long script? Why do you want a shorter script? Or do you want a faster script? $\endgroup$
    – llrs
    Commented Aug 19, 2018 at 10:49
  • $\begingroup$ Did anyone get the correct script for finding out the average read length? $\endgroup$ Commented Dec 17, 2021 at 8:37

2 Answers 2

8
$\begingroup$

This can also be done with regular awk.

awk '{if(NR%4==2) {count++; bases += length} } END{print bases/count}' <fastq_file>

The NR%4==2 count the second line out of every block of 4. length is a built-in that defaults to the length of the line, same as length($0). In this case you can inject you custom printing to the END{} block but countread and countstored will always be the same since the averaging is done on the fly.

$\endgroup$
3
  • 1
    $\begingroup$ Note that, like OP’s code, this will only work on FASTQ files that don’t break the sequence and/or quality string across multiple lines. $\endgroup$ Commented Aug 20, 2018 at 18:01
  • 2
    $\begingroup$ That is correct. However that practice is highly frowned upon so should not be an issue with most FASTQ files $\endgroup$
    – Bioathlete
    Commented Aug 20, 2018 at 22:04
  • $\begingroup$ I've yet to ever encounter a FASTQ file which has sequence or quality on multiple lines, I think for all intensive purposes assuming 4 lines per record should be fine. $\endgroup$ Commented Aug 21, 2018 at 9:43
3
$\begingroup$

This script is wrong because a quality string may start with @. With bioawk, it can be simplified to:

bioawk -c fastx '{ readlength[length($seq)]++; countread++ } END{...}'

The END{} block is the same as your original version.

EDIT: forgot -c fastx is the original answer. Thank @MattBashton for pointing this out.

$\endgroup$
1
  • 1
    $\begingroup$ Using the exact same END{} code from the OP fails in this example with bioawk: illegal field $(), name "seq" $\endgroup$ Commented Aug 20, 2018 at 15:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.