Comment countr les dernières colonnes dupliquées sans les supprimer?

J'ai un file qui contient 4 colonnes. Je veux comparer les trois dernières colonnes et countr combien de fois ils se produisent sans supprimer aucune des lignes. Je veux juste que le count soit présent devant chaque ligne.

Mon file ressemble à ceci:

ID-jacob 4.0 6.0 42.0 ID-elsa 5.0 8.0 45.0 ID-fred 4.0 6.0 42.0 ID-gerard 6.0 8.0 20.0 ID-trudy 5.0 8.0 45.0 ID-tessa 4.0 6.0 42.0 

Mon résultat désiré est:

 3 ID-jacob 4.0 6.0 42.0 2 ID-elsa 5.0 8.0 45.0 3 ID-fred 4.0 6.0 42.0 1 ID-gerard 6.0 8.0 20.0 2 ID-trudy 5.0 8.0 45.0 3 ID-tessa 4.0 6.0 42.0 

J'ai essayé d'utiliser sort et uniq, mais cela ne me donne que la première ligne par ligne dupliquée:

 cat file | sort -k2,4 | uniq -c -f1 > outputfile 

Vous pourriez rencontrer des problèmes pour stocker de gros files en memory, c'est un peu mieux car il ne stocke que les lignes correspondantes, après que sorting ait fait le gros du travail pour mettre les lignes en ordre.

 # Input must be sorted first, then we only need to keep matching lines in memory # Once we reach a non-matching line we print the lines in memory, prefixed by count # with awk, variables are unset to begin with so, we can get away without explicitly initializing { # S2, S3, S4 are saved field values if($2 == S2 && $3 == S3 && $4 == S4) { # if fields 2,3,4 are same as last, save line in array, increment count line[count++] = $0; } else { # new line with fields 2, 3, 4 different # print stored lines, prefixed by the count for(i in line) { print count, line[i]; } # reset counter and array count=0; delete line; # save this line in array, increment count line[count++] = $0; } # store field values to compare with next line read S2 = $2; S3 = $3; S4 = $4; } END{ # on EOF we still have saved lines in array, print last lines for(i in line) { print count, line[i]; } } 

Il est d'usage de sauvegarder des scripts awk dans un file.
Vous pourriez utiliser ceci dans le sens de
sort -k2,4 file | awk -f script

 3 ID-fred 4.0 6.0 42.0 3 ID-jacob 4.0 6.0 42.0 3 ID-tessa 4.0 6.0 42.0 2 ID-elsa 5.0 8.0 45.0 2 ID-trudy 5.0 8.0 45.0 1 ID-gerard 6.0 8.0 20.0 

Cela pourrait aider:

 awk '{ pop[$1] = $2" "$3" "$4; x[$2" "$3" "$4]++; } END { for (name in pop) { if (pop[name] in x) { print x[pop[name]], name, pop[name]; } } }' file 

Il crée deux arrays pop et x. Dans pop, nous avons les keys de column1 et value = colum2 "" column3 "" column4, dans le tableau x, nous avons les valeurs des keys du tableau pop et les valeurs qui countnt les répétitions. Dans la dernière boucle, nous vérifions chaque nom dans la valeur de la table array dans le tableau x.
Cela ne préserve pas votre command.