Question: I used to work with publicly available genomic references, where basic statistics are usually available and if they are not, you have to compute them only once so there is no reason to worry about performance.

Recently I started sequencing project of couple of different species with mid-sized genomes (~Gbp) and during testing of different assembly pipelines I had compute number of unknown nucleotides many times in both raw reads (in fastq) and assembly scaffolds (in fasta), therefore I thought that I would like to optimize the computation.

* For me it is reasonable to expect 4-line formatted fastq files, but general solution is still prefered
* It would be nice if solution would work on gzipped files as well

Q : What is the fastest way (performance-wise) to compute the number of unknown nucleotides (Ns) in fasta and fastq files?

Answer: 
**FASTQ**

As it was pointed out, fastq can be complicated. But in a simple case when you have four lines per record, one possible solution in bash is:

```
sed -n '2~4p' seqs.fastq | grep -io N | wc -l

```

* `sed -n '2~4p'` will print every fourth line
* `grep -o N` will output a line with `N` for every matching symbol
* `wc -l` will count the lines

I suspect this python approach will work faster:

```
cat seqs.fastq | python3 -c "import sys; print(sum(line.upper().count('N') for line in sys.stdin))"

```

**FASTA**

Coreutils:

```
grep -v "^>" seqs.fasta | grep -io N | wc -l

```

Python:

```
cat seqs.fasta | python3 -c "import sys; print(sum(line.upper().count('N') for line in sys.stdin if not line.startswith('>')))"

```
Here are perl 1-liners for fasta and fastq files that are fast enough if you just want totals:

`$ perl -ne 'BEGIN { my $n=0 }; /^>/ or $n += s/N//gi; END { print "N=$n\n" }' contigs.fasta`

For each line of a FASTA file, if not header (/^>/) then it's a sequence line. 
 Substitute Ns, which returns the number of substitutions made, which is added to the total.

`$ zcat reads.fastq | perl -ne 'BEGIN { my $n=0 }; /^[ATCGN]+$/i and $n += s/N//gi; END { print "N=$n\n" }'`

For each sequence line of a FASTQ file, matched by /^[ATCGN]+$/i (i.e. all NTs), then count substitutions made in the same way.

You may use pigz instead of zcat (or gunzip -c) if you have pigz installed.

An uncompressed fastq file of 14M 250bp Illumina reads completed in 40sec.