Uniq -c sur un champ précis ?

Résolu/Fermé
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 - Modifié par Swiss Knight le 17/12/2012 à 17:26
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 - 18 déc. 2012 à 08:36
Salut,

après le problème de concaténation voici (re)venir un problème de comptage d'occurrences...

Sur un fichier à une colonne il est facile de compter les occurrences de chaque entrée avec :
sort filename.txt | uniq -c



mais sur un fichier à plusieurs colonnes, séparées par des virgules, je n'ai rien trouvé dans le man de uniq pour ça...

J'ai bien tenté de faire un :
sort -u -t, -k1 filename.txt > fileout.txt 


ça marche... mais ça ne me compte les occurrences dans la première colonne à la manière de uniq.

Un exemple sera plus parlant, reprenons nos fruits et légumes :
banane, 06-01-1992, 12:58:01    
poire, 15-01-1998, 01:37:43    
banane, 16-01-1998, 20:19:27    
abricot, 21-02-1999, 01:56:51    
céleri, 26-02-1999, 00:17:45    
choux-fleur, 24-01-2002, 08:26:42    
poire, 28-02-2002, 02:18:27    
poire, 17-05-2002, 01:29:26    
carotte, 01-06-2002, 00:19:31    
pomme, 02-06-2002, 20:26:45    

etc.

sur un fichier ne contenant que la 1ère colonne, un uniq -c me donnais par exemple :
  94 poire    
   6 carotte    
  15 pomme 

etc.

mais sur l'exemple ci-dessus, vu qu'il y a plusieurs colonnes ça ne fonctionne plus, et la commande
sort -u -t, -k1 filename.txt > fileout.txt 

arrive bel et bien à me regrouper les occurrences (enfin je crois...) des fruits et légumes pour qu'il n'y ait plus qu'une ligne pour chacun ( ça prend, pour les colonnes 2 et 3, la valeur de la 1ère occurrence du fruit trouvée ), mais ça ne m'indique pas combien il en a trouvé.
Ce serait sympa d'arriver à ça :
  94 poire, 15-01-1998, 01:37:43    
   6 carotte, 01-06-2002, 00:19:31    
  15 pomme, 02-06-2002, 20:26:45 

etc.

Des idées de trucs simples (pas spécialement besoin d'un script de 10 lignes avec des boucles) ?
Est-ce préférable de passer par un fichier temporaire qui ne contient que la 1ère colonne pour faire un uniq -c dessus, simplement ?

Merci encore !!

3 réponses

dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
18 déc. 2012 à 08:36
hello
$ awk '{x[$1]=$0; z[$1]++} END {for(n in x)print z[n], x[n] }' fichier
1 pomme, 02-06-2002, 20:26:45    
3 poire, 17-05-2002, 01:29:26    
1 choux-fleur, 24-01-2002, 08:26:42    
2 banane, 16-01-1998, 20:19:27    
1 abricot, 21-02-1999, 01:56:51    
1 carotte, 01-06-2002, 00:19:31    
1 céleri, 26-02-1999, 00:17:45    
$ 
2
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 110
17 déc. 2012 à 17:50
J'ai trouvé ça en attendant, qui fonctionne pas trop mal, mais ça compte apparemment le séparateur de champs dans le champ :

awk ' {print $1}' filename.txt | sort | uniq -c | sort -nr > fileout.txt


Je me demande s'il n'y a pas plus court, parce que je vois deux fois la commande sort mais je n'arrive pas à faire en sorte qu'elle n'apparaisse qu'une fois, ce qui est peut-être normal en fait.

ça me donne ça :
  94 poire,
   6 carotte,
  15 pomme,

etc.

et un petit sed -i 's/,$//g' fileout.txt
me permet d'enlever la virgule qui a été prise dans le champ $1 alors qu'il s'agit du séparateur de champs.


Si vous voyez plus simple, moins tiré par les cheveux ou plus propre, n'hésitez pas ;)

@+
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
17 déc. 2012 à 18:05
Salut,

$ cat plop 
banane, 06-01-1992, 12:58:01   
poire, 15-01-1998, 01:37:43   
banane, 16-01-1998, 20:19:27   
abricot, 21-02-1999, 01:56:51   
céleri, 26-02-1999, 00:17:45   
choux-fleur, 24-01-2002, 08:26:42   
poire, 28-02-2002, 02:18:27   
poire, 17-05-2002, 01:29:26   
carotte, 01-06-2002, 00:19:31   
pomme, 02-06-2002, 20:26:45

$ sort plop | uniq -c -w 6
      1 abricot, 21-02-1999, 01:56:51   
      2 banane, 06-01-1992, 12:58:01   
      1 carotte, 01-06-2002, 00:19:31   
      1 céleri, 26-02-1999, 00:17:45   
      1 choux-fleur, 24-01-2002, 08:26:42   
      3 poire, 15-01-1998, 01:37:43   
      1 pomme, 02-06-2002, 20:26:45

$

L'idée c'est de ne prendre en compte que les 6 premiers caractères pour la comparaison et l'unicité, par contre cette méthode doit vite être prise à défaut avec d'autres exemples que des fruits et légumes ;-(
0
Swiss Knight Messages postés 1956 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 27 juillet 2016 110
Modifié par Swiss Knight le 17/12/2012 à 21:03
Ouais merci, j'avais vu cette option -w mais j'osais pas trop l'utiliser sur un fichier de plusieurs milliers de lignes sans connaître la longueur des mots du premier champ... Je préfère une solution dont je suis sûr à 100% dans ce cas, parce qu'il ne s'agit bien évidemment pas de fruits et légumes ;-) !
Merci quand même !
https://skorks.com/2010/05/sort-files-like-a-master-with-the-linux-sort-command-bash/
0