Imprimer le compte en double sans supprimer les doublons dans Terminal

Je suis nouveau à travailler avec le terminal sur Mac et j’ai un grand fichier .tsv qui consiste en une liste d’éléments et deux valeurs à côté. Je voudrais pouvoir imprimer le nombre de doublons à côté de la première occurrence de l’élément sans supprimer de données supplémentaires.

Je suis au courant de la coupe -f 1 | sortinger | uniq -c mais cela supprime beaucoup de précieuses données que je voudrais conserver pour l’parsing. Je lis à propos de awk et grep mais je pense que je pourrais utiliser un peu d’aide.

Voici un exemple du fichier que je tente de traiter:

fruit number reference apple 12 342 apple 13 345 apple 43 4772 banana 19 234 banana 73 3242 peach 131 53423 peach 234 3266 peach 242 324 peach 131 56758 peaches 29 2434 

Idéalement, le résultat devrait ressembler à ceci:

 fruit number reference fruit_count apple 12 342 3 apple 13 345 apple 43 4772 banana 19 234 2 banana 73 3242 peach 131 53423 4 peach 234 3266 peach 242 324 peach 131 56758 peaches 29 2434 1 

Est-ce que quelque chose comme ça est même possible? Je peux obtenir la sortie souhaitée en utilisant des formules, mais le fichier est trop volumineux et continue de tomber en panne sur moi. Toute aide serait appréciée.

EDIT: Ajout de ma solution actuelle (qui ne répond pas à mes exigences)

cut -f 1 fruitsample.txt | sort | uniq -c | sed -e 's/ *//' -e 's/ / /'

Cela me donne le nombre prévu, en remplaçant la sortie standard count + space par uniq -c par un caractère de tabulation, mais il sortinge également la ligne d’en-tête et supprime les 2ème et 3ème colonnes.

Sur Excel, je peux utiliser la formule =IF(COUNTIF(A$2:A2,A2)=1,COUNTIF(A:A,A2),"") et la remplir. Le fichier avec lequel je travaille est constitué de près de 680 000 lignes de données et Excel bloque les tentatives de calcul de ce nombre de lignes.

Comme je l’ai mentionné, je suis un débutant à la recherche de conseils. Je ne suis pas aussi familier avec awk ou grep. Merci encore!

awk à la rescousse!

 awk 'NR==FNR {a[$1]++; next} FNR==1 {print $0, "fruit_count"; next} $1 in a {$(NF+1)=a[$1]; delete a[$1]}1' file{,} | column -t fruit number reference fruit_count apple 12 342 3 apple 13 345 apple 43 4772 banana 19 234 2 banana 73 3242 peach 131 53423 4 peach 234 3266 peach 242 324 peach 131 56758 peaches 29 2434 1 

pour l’explication de l’idée principale, j’utiliserai une structure plus simple sans en-tête et des données non sortingées

 $ cat file apple banana apple apple cherry banana $ awk 'NR==FNR {a[$1]++; next} # in the first pass, save key counts $1 in a # if the key in map {$(NF+1)=a[$1]; # add the count as a last column delete a[$1]} # remove key from map 1 # print ' file{,} | # bash shorthand for: file file column -t # pretty print columns apple 3 banana 2 apple apple cherry 1 banana 

pour l’exemple simplifié, en utilisant unix toolchain, vous pouvez obtenir la même chose avec

 join -a1 -11 -22 -o1.2,2.1 <(cat -n file) <(cat -n file | sort -k2 | uniq -c -f1) 

l'ajout d'en-tête nécessitera plus de jonglage; c'est où awk brille.

Un autre utilisant awk et double- tac :

 $ tac file | awk ' NR>1 {print q, (p==$1?"":++c)} # p previous first field, q previous record {c=(p==$1?c+1:0); p=$1; q=$0} # c is the counter END {print q, "fruit_count"} ' | tac fruit number reference fruit_count apple 12 342 3 apple 13 345 apple 43 4772 banana 19 234 2 banana 73 3242 peach 131 53423 4 peach 234 3266 peach 242 324 peach 131 56758 peaches 29 2434 1 

Cela fait ce que vous voulez en un seul passage du fichier d’entrée et ne stocke que les valeurs pour 1 fruit à la fois dans la mémoire, il ne devrait donc pas avoir de problèmes de performance ou de mémoire, même si votre fichier est trop gros pour MS-Excel:

 $ cat tst.awk NR==1 { print $0, "fruit_count"; next } $1 != prev { prt() } { arr[++cnt] = $0; prev = $1 } END { prt() } function prt( i) { if (cnt) { print arr[1], cnt for (i=2; i <= cnt; i++) { print arr[i] } delete arr cnt = 0 } } $ awk -f tst.awk file | column -t fruit number reference fruit_count apple 12 342 3 apple 13 345 apple 43 4772 banana 19 234 2 banana 73 3242 peach 131 53423 4 peach 234 3266 peach 242 324 peach 131 56758 peaches 29 2434 1