web-dev-qa-db-fra.com

Trier les données dans l'ordre décroissant de la première colonne, pour des valeurs égales, utiliser la deuxième colonne dans l'ordre croissant

Permettez-moi de clarifier:

Supposons que j'ai quelques mots clés avec la fréquence de leur utilisation:

12 Hi
7  Hash
7  C++  
9  Superuser
17 Stackoverflow
9  LaTeX  
42 Life
9  Ubuntu

Ce que je veux, c'est trier ces données en fonction de la fréquence en ordre décroissant et s'il y a des valeurs égales, il devrait utiliser la deuxième colonne en ordre croissant.

sort -n -r foo.txt

La première partie mais la deuxième colonne sont-elles également reversed:

42 Life
17 Stackoverflow
12 Hi
9  Ubuntu
9  Superuser
9  LaTeX  
7  Hash
7  C++

Comment puis-je obtenir les résultats suivants?

42 Life
17 Stackoverflow
12 Hi
9  LaTeX  
9  Superuser
9  Ubuntu
7  C++ 
7  Hash

Je pense que je dois utiliser -k argument mais je ne sais pas comment!

Je veux savoir comment cela peut être fait en utilisant uniquement la commande sort de bash. Cependant, s'il n'est pas possible d'y parvenir uniquement par sort, les autres commandes doivent être compatibles avec Bourne Shell.

22
Pouya

Spécifiez les clés de tri séparément avec les critères:

sort -k1,1nr -k2,2 inputfile

Cela spécifie que la première clé est triée numériquement dans l'ordre inverse tandis que la seconde est triée selon l'ordre de tri par défaut.

Citant de tri POSIX :

- k keydef

L'argument keydef est une définition de champ de clé de tri restreint. Le format de cette définition est:

field_start [ type] [ , field_end [ type]]

field_start et field_end définissez un champ clé limité à une partie de la ligne (voir la section DESCRIPTION ÉTENDUE), et le type est un modificateur de la liste des les caractères "b", "d", "f", "i", "n", "r". Le modificateur "b" doit se comporter comme le -b, mais ne s'applique qu'à field_start ou field_end auquel il est attaché. Les autres modificateurs se comporteront comme les options correspondantes, mais ne s'appliqueront qu'au champ clé auquel ils sont attachés; ils auront cet effet s'ils sont spécifiés avec field_start, field_end, ou les deux. Si un modificateur est attaché à un field_start ou à un field_end, aucune option ne s'applique à l'un ou l'autre. Les implémentations doivent prendre en charge au moins neuf occurrences de -k option, qui doit être significative dans l'ordre de la ligne de commande. Sinon -k option est spécifiée, une clé de tri par défaut de la ligne entière doit être utilisée.

Lorsqu'il y a plusieurs champs de clé, les clés ultérieures ne seront comparées qu'après que toutes les clés antérieures auront été égales. Sauf lorsque le -u option est spécifiée, les lignes qui comparent autrement égales doivent être ordonnées comme si aucune des options -d, -f, -i, -n, ou -k étaient présents (mais avec -r toujours en vigueur, si spécifié) et avec tous les octets dans les lignes significatifs pour la comparaison. L'ordre dans lequel les lignes qui se comparent toujours égales sont écrites n'est pas spécifié.

Cela produirait:

42 Life
17 Stackoverflow
12 Hi
9  LaTeX
9  Superuser
9  Ubuntu
7  C++
7  Hash
31
devnull