efficient counting of dinucleotides/trinucleotides on fastq reads? What's an efficient way of counting of dinucleotides/trinucleotide pattern on fastq.gz file reads?

I know there are tools like seqtk that will be very efficient at reading through the .fastq.gz files, and tools like cutadapt that are good at finding long(ish) adapter patterns in the fastq.gz PE of files, but, what would be the best tool to count the number of reads where a di-/trinucleotide is present N-number of times in the read? 

E.g.

countingtool --pattern CGC file_R1.fastq.gz


Result: column two is number of times the pattern is seen (exclusive numbers, no overlap)

CGC    0     51341234
CGC    1     13948130
CGC    2      1234344
CGC    3        51344
CGC    4         1343
Well, I'm sure you can find a more efficient approach, but here's a simplistic solution using standard UNIX tools:

zcat file.fastq.gz | grep CGC | 
    awk -F'CGC' 'NR%4==2{a[NF-1]++}END{for(i in a){print i,a[i]}}' |
         sort -rnk2   


I tested this on a 2.6G fastq file (exome data) and it took:

real    1m18.987s
user    1m41.392s
sys     0m10.684s


On a 66G WGS sequence file, it took:

real    34m6.771s
user    40m16.452s
sys     4m10.176s


The extra grep CGC isn't needed, you can do the match in awk, but it does speed things up a little bit. You can always get the reads with 0 matches by counting the number of reads and subtracting the ones with 1. Alternatively, remove the grep:

zcat file.fq.gz | awk -F'CGC' 'NR%4==2{a[NF-1]++}END{for(i in a){print i,a[i]}}' |
    sort -rnk2   




Following the OP's suggestion, I also tested with pigz and, it turns out, pigz can fly!

time unpigz -c exome.fastq.gz | grep CGC | 
    awk -F'CGC' 'NR%4==2{a[NF-1]++}END{for(i in a){print i,a[i]}}' |
         sort -rnk2


real    0m44.012s
user    1m19.544s
sys     0m14.900s


And for the 66G WGS:

real    17m29.935s
user    29m23.816s
sys     5m17.856s