countr plusieurs templates en un seul passage avec grep?

J'ai écrit une boucle grep pour countr itérativement les sortingnukeyotides d'ADN dans un file fasta d'ADN gzip contenant des séquences d'ADN par exemple

declare -a sorting=(AAA AAC AAG AAT CAA .. etc) for i in ${sorting[@]} do gzip -cd gencode.v18.pc_transcripts.fa.gz | grep -v "^>" | grep -o $i | wc -l done 

Où le file fasta est dans ce format (bien que beaucoup plus grand)

 head test.fa >id1 TTTTTAAAAA >id2 GGGGGCCCCC etc.. 

Bien que cela fonctionne (c'est-à-dire count les occurrences de chaque sortingnukeyotide), cela me semble très inefficace car il doit passer datatables 64 fois (une fois pour chaque sortingnukeyotide possible).

Ma question est comment utiliser bash ou grep est-il un moyen je peux countr chaque sortingnucleotide en un seul passage à travers le file (comme les files sont assez grands)?

THX

 IFS=$'\n' gzip -dc file.gz | grep -v '^>' | grep -Foe "${sorting[*]}" | sort | uniq -c 

Mais au fait, AAAC correspond à AAA et AAC , mais grep -o ne produira qu'un seul d'entre eux. Est-ce que c'est ce que tu veux? Aussi, combien d'occurrences d' AAA dans AAAAAA ? 2 ou 4 ( [AAA]AAA , A[AAA]AA , AA[AAA]A , AAA[AAA] )?

Peut-être que vous voulez plutôt:

 gzip -dc file.gz | grep -v '^>' | fold -w3 | grep -Fxe "${sorting[*]}" | sort | uniq -c 

C'est divisé les lignes en groupes de 3 caractères et countr les occurrences en tant que lignes complètes (findait 0 occurrence d' AAA dans ACAAATTCG (comme ACA AAT TCG )).

Ou d'autre part:

 gzip -dc file.gz | awk ' BEGIN{n=ARGC;ARGC=0} !/^>/ {l = length - 2; for (i = 1; i <= l; i++) a[substr($0,i,3)]++} END{for (i=1;i<n;i++) printf "%s: %d\n", ARGV[i], a[ARGV[i]]}' "${sorting[@]}" 

(findait 4 occurrences d' AAA dans AAAAAA ).

Le deuxième exemple de stéphane-chazelas est génial, mais la command de sort pourrait vraiment ralentir le process au fur et à mesure que datatables s'agrandissent.

Peut-on supposer que les caractères des lignes non-entêtes sont des nukeyotides valides? Cela éliminerait le sorting correspondant.

gzip -dc file.gz | grep -v '^>' | fold -w3 | awk '{a[$0]++} END{for(codon in a) {printf "%s: %d\n", codon, a[codon]}'

Sur une note connexe, la conversion des jetons de 3 nukeyotides en octal octal (ou binary à partir de là) réduirait la taille du stream de données de 2/3 ou 1/3.

gzip -dc file.gz | grep -v '^>' | tr ACGT 0123 | fold -w3 | cat <(echo "obase=8; ibase=4;" ) - | bc | xargs printf "%02d\n" | tee foo.octal | xxd -r -p > foo.bin

Retour aux nukeyotides

cat foo.bin | xxd -p | fold -w2 | cat <(echo "obase=4; ibase=8;") - | bc | xargs printf "%03d" | tr 0123 ACGT

xargs est probablement l'étape limitante ici, peut-être en analysant N lignes à la fois, cela corrigera cela ou en utilisant gnu parallèle.